我在这里有一个测试用例:
http://www.libsys.und.edu/dev/scroll-test.html
它有一个包含很长链接列表的DIV。我想将DIV滚动到给定的链接。在我的测试用例中,通过按下JSTOR按钮完成,将按钮推进到JSTOR链接。在实际生产样本中,将基于键盘输入选择链接。因此,例如,按“B”会将其推进到第一个“B”链接,即生物学文摘。
我的测试用例中的预期结果是:我单击JSTOR,它会滚动,因此JSTOR位于DIV的顶部。这可能涉及向下或向上滚动,具体取决于DIV已经滚动了多远。
实际结果取决于DIV是否已经滚动。
如果DIV根本没有滚动 ,那么它在所有浏览器中都能正常工作。
如果已经滚动了DIV(甚至一点点),结果如下:
此外,在某些我无法令人满意地识别的情况下,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();
});
答案 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;
}
}());