我在div中有20个列表项,一次只能显示5个。滚动到项目#10,然后项目#20的好方法是什么?我知道所有物品的高度。
scrollTo
插件可以做到这一点,但是如果没有真正进入它,其源代码就不容易理解。 我不想使用此插件。
假设我有一个函数需要2个元素$parentDiv
,$innerListItem
,$innerListItem.offset().top
和$innerListItem.positon().top
都没有为$ parentDiv提供正确的scrollTop。
答案 0 :(得分:222)
$innerListItem.position().top
实际上是相对于其第一个定位祖先的.scrollTop()
。因此,计算正确$parentDiv.scrollTop()
值的方法是首先确保定位$parentDiv
。如果它还没有明确的position
,请使用position: relative
。元素$innerListItem
及其所有祖先$parentDiv
都需要没有明确的位置。现在,您可以使用:
$innerListItem
// Scroll to the top
$parentDiv.scrollTop($parentDiv.scrollTop() + $innerListItem.position().top);
// Scroll to the center
$parentDiv.scrollTop($parentDiv.scrollTop() + $innerListItem.position().top
- $parentDiv.height()/2 + $innerListItem.height()/2);
答案 1 :(得分:138)
这是我自己的插件(将元素置于列表顶部。特别适用于overflow-y : auto
。可能不适用于overflow-x
!):
注意:elem
是页面将滚动到的元素的HTML选择器。 jQuery支持的任何内容,例如:#myid
,div.myclass
,$(jquery object)
,[dom object]等。
jQuery.fn.scrollTo = function(elem, speed) {
$(this).animate({
scrollTop: $(this).scrollTop() - $(this).offset().top + $(elem).offset().top
}, speed == undefined ? 1000 : speed);
return this;
};
如果您不需要动画,请使用:
jQuery.fn.scrollTo = function(elem) {
$(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top);
return this;
};
使用方法:
$("#overflow_div").scrollTo("#innerItem");
$("#overflow_div").scrollTo("#innerItem", 2000); //custom animation speed
注意:#innerItem
可以位于#overflow_div
内的任何位置。它实际上不一定是直接的孩子。
在Firefox(23)和Chrome(28)中测试过。
如果您想滚动整个页面,请检查this question。
答案 2 :(得分:31)
我已经调整了Glenn Moss的回答,说明溢出div可能不在页面顶部。
parentDiv.scrollTop(parentDiv.scrollTop() + (innerListItem.position().top - parentDiv.position().top) - (parentDiv.height()/2) + (innerListItem.height()/2) )
我在带有响应式模板的Google地图应用程序中使用此功能。关于分辨率> 800px,列表位于地图的左侧。关于决议< 800列表在地图下方。
答案 3 :(得分:5)
上面的答案将内部元素定位在溢出元素的顶部,即使它在溢出元素内部也是如此。我不想这样,所以如果元素在视图中,我将其修改为不更改滚动位置。
jQuery.fn.scrollTo = function(elem, speed) {
var $this = jQuery(this);
var $this_top = $this.offset().top;
var $this_bottom = $this_top + $this.height();
var $elem = jQuery(elem);
var $elem_top = $elem.offset().top;
var $elem_bottom = $elem_top + $elem.height();
if ($elem_top > $this_top && $elem_bottom < $this_bottom) {
// in view so don't do anything
return;
}
var new_scroll_top;
if ($elem_top < $this_top) {
new_scroll_top = {scrollTop: $this.scrollTop() - $this_top + $elem_top};
} else {
new_scroll_top = {scrollTop: $elem_bottom - $this_bottom + $this.scrollTop()};
}
$this.animate(new_scroll_top, speed === undefined ? 100 : speed);
return this;
};
答案 4 :(得分:2)
已接受的答案仅适用于可滚动元素的直接子元素,而其他答案并未将其子元素置于可滚动元素的中心。
HTML示例:
<div class="scrollable-box">
<div class="row">
<div class="scrollable-item">
Child 1
</div>
<div class="scrollable-item">
Child 2
</div>
<div class="scrollable-item">
Child 3
</div>
<div class="scrollable-item">
Child 4
</div>
<div class="scrollable-item">
Child 5
</div>
<div class="scrollable-item">
Child 6
</div>
<div class="scrollable-item">
Child 7
</div>
<div class="scrollable-item">
Child 8
</div>
<div class="scrollable-item">
Child 9
</div>
<div class="scrollable-item">
Child 10
</div>
<div class="scrollable-item">
Child 11
</div>
<div class="scrollable-item">
Child 12
</div>
<div class="scrollable-item">
Child 13
</div>
<div class="scrollable-item">
Child 14
</div>
<div class="scrollable-item">
Child 15
</div>
<div class="scrollable-item">
Child 16
</div>
</div>
</div>
<style>
.scrollable-box {
width: 800px;
height: 150px;
overflow-x: hidden;
overflow-y: scroll;
border: 1px solid #444;
}
.scrollable-item {
font-size: 20px;
padding: 10px;
text-align: center;
}
</style>
构建一个小型jQuery插件:
$.fn.scrollDivToElement = function(childSel) {
if (! this.length) return this;
return this.each(function() {
let parentEl = $(this);
let childEl = parentEl.find(childSel);
if (childEl.length > 0) {
parentEl.scrollTop(
parentEl.scrollTop() - parentEl.offset().top + childEl.offset().top - (parentEl.outerHeight() / 2) + (childEl.outerHeight() / 2)
);
}
});
};
用法:
$('.scrollable-box').scrollDivToElement('.scrollable-item:eq(12)');
说明:
parentEl.scrollTop(...)
设置滚动条的当前垂直位置。
parentEl.scrollTop()
获取滚动条的当前垂直位置。
parentEl.offset().top
获取 parentEl 相对于文档的当前坐标。
childEl.offset().top
获取 childEl 相对于文档的当前坐标。
parentEl.outerHeight() / 2
获得子元素的外部高度的一半(因为我们希望它居中)。
使用时:
$(parent).scrollDivToElement(child);
父级是可滚动的div,它可以是DOM元素的字符串或jQuery对象。
子是您要滚动到的任何子,它可以是DOM元素的字符串或jQuery对象。
答案 5 :(得分:0)
在玩了很长时间之后,这就是我想出来的:
$("#basketListGridHolder").scrollTo('tr[data-uid="' + basketID + '"]');
我称之为
{{1}}
答案 6 :(得分:0)
我写了这两个函数,让我的生活更轻松:
function scrollToTop(elem, parent, speed) {
var scrollOffset = parent.scrollTop() + elem.offset().top;
parent.animate({scrollTop:scrollOffset}, speed);
// parent.scrollTop(scrollOffset, speed);
}
function scrollToCenter(elem, parent, speed) {
var elOffset = elem.offset().top;
var elHeight = elem.height();
var parentViewTop = parent.offset().top;
var parentHeight = parent.innerHeight();
var offset;
if (elHeight >= parentHeight) {
offset = elOffset;
} else {
margin = (parentHeight - elHeight)/2;
offset = elOffset - margin;
}
var scrollOffset = parent.scrollTop() + offset - parentViewTop;
parent.animate({scrollTop:scrollOffset}, speed);
// parent.scrollTop(scrollOffset, speed);
}
并使用它们:
scrollToTop($innerListItem, $parentDiv, 200);
// or
scrollToCenter($innerListItem, $parentDiv, 200);