如何在浏览器中一致滚动到DIV的子元素?

时间:2011-07-25 23:34:01

标签: javascript jquery scroll

我在这里有一个测试用例:

http://www.libsys.und.edu/dev/scroll-test.html

它有一个包含很长链接列表的DIV。我想将DIV滚动到给定的链接。在我的测试用例中,通过按下JSTOR按钮完成,将按钮推进到JSTOR链接。在实际生产样本中,将基于键盘输入选择链接。因此,例如,按“B”会将其推进到第一个“B”链接,即生物学文摘。

我的测试用例中的预期结果是:我单击JSTOR,它会滚动,因此JSTOR位于DIV的顶部。这可能涉及向下或向上滚动,具体取决于DIV已经滚动了多远。

实际结果取决于DIV是否已经滚动。

如果DIV根本没有滚动 ,那么它在所有浏览器中都能正常工作。

如果已经滚动了DIV(甚至一点点),结果如下:

  1. Firefox向下滚动并将JSTOR放在DIV的底部
  2. Chrome向下滚动并将JSTOR放在DIV的底部。 (但见下文)
  3. Safari向下滚动并将JSTOR放在DIV的底部。 (但见下文)
  4. Chrome向下滚动并将JSTOR放置在DIV的底部
  5. Opera向下滚动并将JSTOR放在DIV的顶部
  6. 此外,在某些我无法令人满意地识别的情况下,Chrome和Safari都会向下滚动并将JSTOR链接垂直居中放置在DIV的中间中。

    Opera是唯一能够始终如一地实现我期望的浏览器。 Firefox和IE以不同的方式做到这一点,但至少以不同的方式始终,并且他们的行为相互匹配;我不知道Chrome和Safari的行为是什么。

    那么 - 是否有某种方法可以滚动DIV,使得目标链接总是在浏览器中相对于其父级位于相同的位置?我甚至不关心它是否在顶部,真的,尽管这对我来说最有意义。只要我能够以同样的方式持续工作,我会很高兴。

    对于长期记录,这是我的CSS和JS; HTML只是一个很长的DIV内部链接列表,ID为“box”。我尝试用这个来制作一个JS Fiddle,但它在我身上死了 - 我认为它不喜欢HTML源代码的长度。

    CSS:

    #box {
        width: 300px;
        height: 200px;
        overflow: auto;
        position: relative;
    }
    
    #box ul {
        margin: 0;
        padding: 0;
        list-style: none;
    }
    

    JS:

    // I'm running scrollTop() and position().top through Math.floor() because
    // Firefox likes reporting fractional values for pixels, for some reason.
    function reportOffsets(){
        var offset = Math.floor($("#box").scrollTop());
        var position = Math.floor($("#jstor").position().top);
        $("#counter").html(offset+"px; J "+position+"px");
    }
    
    $(document).ready(function(){
        // When the box scrolls, tell me its current offset and where JSTOR is.
        $("#box").scroll(reportOffsets);
    
        $("#go").click(function(e){
            // Get the current position of the JSTOR link.
            var position = Math.floor($("#jstor").position().top);
    
            // Scroll the box down to it.
            $("#box").scrollTop(position);
    
            $("#jstor").focus();
    
            reportOffsets();
        });
    
        reportOffsets();
    });
    

2 个答案:

答案 0 :(得分:12)

DOM方法scrollIntoView()应该正是您想要的。有一个optional alignWithTop参数,默认为true。如果您使用false(如Demo中所述),则元素会与底部对齐。

答案 1 :(得分:-1)

使用锚点。 // SO的额外垃圾

修改

下面是一个基于锚点的解决方案,以便展示我在谈论的内容。原帖有点简短。由于某些原因它在IE中不起作用,它只是看不到锚。所以 scrollIntoView 解决方案是最好的,因为它似乎至少可以回到IE 6。

传递元素以滚动到 inPageNav 。它在DOM之前放置一个锚点,然后在URL中添加一个锚点名称。插入锚点对页面布局没有影响。

该功能仅创建一个锚点,并且每次都将其移动到所需位置非常有效。但不如 scrollIntoView

var inPageNav = (function() {

  // Store the anchor
  var anchor;
  var anchorHref;

  return function(el) {

    var anchorName;

    // Create an anchor if don't already have one
    if (!anchor) {
      anchor = document.createElement('a');
      anchorName = 'foo' + (new Date().getTime()); 
      anchor.name = anchorName;
      anchorHref = document.location.href.replace(/#.*/,'') +  
                                             '#' + anchorName;
    }

    // Move anchor and go there
    el.parentNode.insertBefore(anchor, el);
    document.location.href = anchorHref;
  }
}());