[jquery] How do I scroll a row of a table into view (element.scrollintoView) using jQuery?

I'm dynamically adding rows to a table using jQuery. The table is inside a div which has overflow:auto thus causing a vertical scrollbar.

I now want to autoscroll my container div to the last row. What's the jQuery version of tr.scrollintoView()?

This question is related to jquery scroll

The answer is


This following works better if you need to scroll to an arbitrary item in the list (rather than always to the bottom):

function scrollIntoView(element, container) {
  var containerTop = $(container).scrollTop(); 
  var containerBottom = containerTop + $(container).height(); 
  var elemTop = element.offsetTop;
  var elemBottom = elemTop + $(element).height(); 
  if (elemTop < containerTop) {
    $(container).scrollTop(elemTop);
  } else if (elemBottom > containerBottom) {
    $(container).scrollTop(elemBottom - $(container).height());
  }
}

Plugin that scrolls (with animation) only when required

I've written a jQuery plugin that does exactly what it says on the tin (and also exactly what you require). The good thing is that it will only scroll container when element is actually off. Otherwise no scrolling will be performed.

It works as easy as this:

$("table tr:last").scrollintoview();

It automatically finds closest scrollable ancestor that has excess content and is showing scrollbars. So if there's another ancestor with overflow:auto but is not scrollable will be skipped. This way you don't need to provide scrollable element because sometimes you don't even know which one is scrollable (I'm using this plugin in my Sharepoint site where content/master is developer independent so it's beyond my control - HTML may change when site is operational so can scrollable containers).


I found a case (overflow div > table > tr > td) in which scrolling to the relative position of the tr does not work. Instead, I had to scroll the overflow container (div) using scrollTop to <tr>.offset().top - <table>.offset().top. Eg:

$('#container').scrollTop( $('#tr').offset().top - $('#td').offset().top )

_x000D_
_x000D_
$( "#yourid" )[0].scrollIntoView();
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p id="yourid">Hello world.</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>
_x000D_
_x000D_
_x000D_


I couldn't add a comment to Abhijit Rao's answer above, so I am submitting this as an additional answer.

I needed to have the table column scroll into view on a wide table, so I added the scroll left features into the function. As someone mentioned, it jumps when it scrolls, but it worked for my purposes.

function scrollIntoView(element, container) {
  var containerTop = $(container).scrollTop();
  var containerLeft = $(container).scrollLeft();
  var containerBottom = containerTop + $(container).height();
  var containerRight = containerLeft + $(container).width();

  var elemTop = element.offsetTop;
  var elemLeft = element.offsetLeft;
  var elemBottom = elemTop + $(element).height();
  var elemRight = elemLeft + $(element).width();

  if (elemTop < containerTop) {
    $(container).scrollTop(elemTop);
  } else if (elemBottom > containerBottom) {
    $(container).scrollTop(elemBottom - $(container).height());
  }

  if(elemLeft < containerLeft) {
    $(container).scrollLeft(elemLeft);
  } else if(elemRight > containerRight) {
    $(container).scrollLeft(elemRight - $(container).width());
  }
}

much simpler:

$("selector for element").get(0).scrollIntoView();

if more than one item returns in the selector, the get(0) will get only the first item.


If you just want to scroll, you could use jQuery's scrollTop method. http://docs.jquery.com/CSS/scrollTop

var table = jQuery( 'table' );
table.scrollTop( table.find( 'tr:last' ).scrollTop() );

Something like that maybe?


This runnable example shows how to use scrollIntoView() which is supported in all modern browsers: https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView#Browser_Compatibility

The example below uses jQuery to select the element with #yourid.

_x000D_
_x000D_
$( "#yourid" )[0].scrollIntoView();
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p id="yourid">Hello world.</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>_x000D_
<p>..</p>
_x000D_
_x000D_
_x000D_


Same from above with little modification

_x000D_
_x000D_
function focusMe() {_x000D_
       var rowpos = $('#FocusME').position();_x000D_
        rowpos.top = rowpos.top - 30;_x000D_
        $('#container').scrollTop(rowpos.top);_x000D_
    }
_x000D_
<html>_x000D_
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>_x000D_
<body>_x000D_
    <input type="button" onclick="focusMe()" value="focus">_x000D_
    <div id="container" style="max-height:200px;overflow:scroll;">_x000D_
        <table>_x000D_
            <tr>_x000D_
                <td>1</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>2</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>3</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>4</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>5</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>6</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>7</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>8</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>9</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr id="FocusME">_x000D_
                <td>10</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>11</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>12</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>13</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>14</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>15</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>16</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>17</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>18</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>19</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
            <tr>_x000D_
                <td>20</td>_x000D_
                <td></td>_x000D_
            </tr>_x000D_
        </table>_x000D_
    </div>_x000D_
</body>_x000D_
_x000D_
</html>
_x000D_
_x000D_
_x000D_


var elem=jQuery(this);
elem[0].scrollIntoView(true);