jquery 如何滚动到溢出的Div中的元素?

qvtsj1bj  于 2022-12-18  发布在  jQuery
关注(0)|答案(7)|浏览(190)

我在一个div中有20个列表项,一次只能显示5个。滚动到第10项,然后滚动到第20项的好方法是什么?我知道所有项的高度。
scrollTo插件可以做到这一点,但如果不深入了解它,它的源代码就不太容易理解。我不想使用这个插件。
假设我有一个函数,它包含两个元素$parentDiv$innerListItem$innerListItem.offset().top$innerListItem.positon().top都不能为$parentDiv提供正确的scrollTop。

wwtsj6pe

wwtsj6pe1#

$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);
jfgube3f

jfgube3f2#

这是我自己的插件(将把元素放在列表的顶部。特别是overflow-y : auto。可能不适用于overflow-x!):

注意elem是页面将滚动到的元素的HTML选择器。jQuery支持的任何内容,如:#myiddiv.myclass$(jquery object)、[dom对象]等。

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

zy1mlcev

zy1mlcev3#

我调整了Glenn Moss的答案,以说明溢出div可能不在页面顶部的事实。

parentDiv.scrollTop(parentDiv.scrollTop() + (innerListItem.position().top - parentDiv.position().top) - (parentDiv.height()/2) + (innerListItem.height()/2)  )

我在一个带有响应模板的谷歌Map应用程序上使用这个。在分辨率〉800px时,列表在Map的左侧。在分辨率〈800时,列表在Map的下方。

mxg2im7a

mxg2im7a4#

上面的答案会把inner元素放在overflow元素的顶部,即使它在overflow元素的内部可见。我不希望这样,所以我修改了它,如果元素在视图中,不改变滚动位置。

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;
};
rqdpfwrv

rqdpfwrv5#

可接受的答案只适用于可滚动元素的直接子元素,而其他答案没有将子元素置于可滚动元素的中心。
示例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)');

说明:

  1. parentEl.scrollTop(...)设置滚动条的当前垂直位置。
  2. parentEl.scrollTop()获取滚动条的当前垂直位置。
  3. parentEl.offset().top获取parentEl相对于文档的当前坐标。
  4. childEl.offset().top获取childEl相对于文档的当前坐标。
  5. parentEl.outerHeight() / 2得到子元素的外部高度的一半(因为我们希望它居中)。
    1.使用时:
    $(parent).scrollDivToElement(child);

parent是可滚动的div,可以是字符串或DOM元素的jQuery对象。
child是要滚动到的任何子元素,它可以是字符串或DOM元素的jQuery对象。

Codepen demo

zmeyuzjn

zmeyuzjn6#

我编写这两个函数是为了让我的工作更轻松:

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);
cyej8jka

cyej8jka7#

在玩了很长时间之后,这是我想出的:

jQuery.fn.scrollTo = function (elem) {
        var b = $(elem);
        this.scrollTop(b.position().top + b.height() - this.height());
    };

我这样称呼它

$("#basketListGridHolder").scrollTo('tr[data-uid="' + basketID + '"]');

相关问题