如何使用jQuery将表的一行滚动到视图(element.scrollintoView)中?


74

我正在使用jQuery向表中动态添加行。的table是内部的divoverflow:auto从而导致垂直滚动条。

现在,我想将容器自动滚动div到最后一行。什么是jQuery版本tr.scrollintoView()


10
按照这个答案,这显然是所有主要浏览器都支持的内置DOM功能。完全element.scrollIntoView()可以。
柯克·沃尔

Answers:


78
var rowpos = $('#table tr:last').position();

$('#container').scrollTop(rowpos.top);

应该做的把戏!


4
我发现了一种情况,这种情况与预期不符,在以下来源中添加了一个答案,但来源略有不同。
user1338062 2012年

这不适用于datatable的新fixed scrolling功能/插件。
洛伦兹·洛绍尔

85

如果您需要滚动到列表中的任意项(而不是总是滚动到底部),则下面的效果更好:

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());
  }
}

8
先生,这不仅是答案,而且是解决方案。谢谢。
见证2010年

1
您可以删除容器参数并将其替换为var container = element.offsetParent; ...
Laurens Holst

2
@Laurens:仅当scrollable元素是子对象的直接父级时才有效。一个更可靠的解决方案是迭代其祖先,直到找到.css(“ overflow”)返回“ auto”或“ scroll”的元素。
罗伯特·J·沃克

2
您的第四行不应该是var elemTop = element.get(0).offsetTop吗?直到我这样做,代码才起作用。
雅克

1
尽管此解决方案几乎可以起作用,但存在严重问题。一种是错字,但更严重的是它不能优雅地处理具有任何高度的物品。更好的解决方案是@Robert Koritnik的插件
boatcoder

29

仅在需要时滚动(带有动画)的插件

我已经编写了一个jQuery插件,该插件的功能完全符合锡盒上的要求(也可以满足您的要求)。好处是,仅在元素实际上处于关闭状态时才滚动容器。否则,将不会执行滚动。

它是如此简单:

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

它会自动查找内容过多并显示滚动条的最接近的可滚动祖先。因此,如果有另一个祖先overflow:auto但不可滚动,将被跳过。这样,您不需要提供可滚动的元素,因为有时您甚至都不知道哪个元素是可滚动的(我在我的Sharepoint网站中使用了此插件,其中内容/母版与开发人员无关,所以这超出了我的控制-HTML可能会更改网站运行时,可滚动容器也可以)。


这确实有效。试图修复@Abhijit Rao的那个问题,但是有很多问题。这只是工作。
boatcoder 2012年

@ Mark0978:但是请注意,我必须对其进行更新才能与jQuery 1.8+一起正常使用。自定义选择器定义必须与1.8+完全不同。
罗伯特·科里特尼克

1
从GitHub获得了插件,并按承诺顺利进行。很好!
Bernoulli IT

自更新以来已有四年了,此插件仍然具有魅力。我在有角度的指令中使用了它:)
Shaunak

1
四年后,该插件对我不起作用-有时几乎错过了目标的标记,但看不到目标。今天,假设目标只是一个元素,我将使用javascript: var target = $(selector); target.get(0).scrollIntoView();
subsci 2015年

19

简单得多:

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

如果选择器中返回多个项目,则get(0)将仅获得第一项。


这也会影响页面的滚动。因此,这是行不通的。
雅克2012年

这不做动画,也不处理可滚动div中的滚动。
boatcoder

这不会做动画,但是我发现动画解决方案在我的特殊用例中失败了,这种特殊用例的元素非常长。动画解决方案有时会以很小的偏移量错过标记。@ Mark0978我的用例是一个可滚动的div –不知道为什么在我的情况下可以使用,但不能在您的情况下使用
subsci 2015年

5

此可运行示例演示了如何使用所有现代浏览器都支持的scrollIntoView():https : //developer.mozilla.org/zh-CN/docs/Web/API/Element.scrollIntoView#Browser_Compatibility

下面的示例使用jQuery选择的元素#yourid

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




2

我发现了一种情况(溢出div>表> tr> td),其中无法滚动到tr的相对位置。相反,我不得不使用scrollTop滚动溢出容器(div)<tr>.offset().top - <table>.offset().top。例如:

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

2

与上面相同,几乎没有修改

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

</html>


0

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


滚动整个页面,实际上是@BarryStaes的答案的副本
Mark Carpenter Jr,

0

我无法在上述Abhijit Rao的答案中添加评论,因此,我将其作为其他答案提交。

我需要使表格列滚动到宽表上的视图中,因此我向功能添加了向左滚动功能。正如有人提到的那样,它在滚动时会跳转,但是它对我有用。

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());
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.