Javascript 如何使用jQuery获取要滚动到视图中的元素?

Javascript 如何使用jQuery获取要滚动到视图中的元素?,javascript,jquery,Javascript,Jquery,我有一个HTML文档,其中包含使用的网格格式的图像。有一个名为DOM的方法,所有主要浏览器都支持该方法,该方法将使元素与视口的顶部/左侧对齐(或尽可能靠近) 在受支持的浏览器上,您可以提供以下选项: $("#myImage")[0].scrollIntoView({ behavior: "smooth", // or "auto" or "instant" block: "start" // or "end" }); 或者,如果所有元素都有唯一的ID,您只需更改对象的散列属性即

我有一个HTML文档,其中包含使用
  • 的网格格式的图像。有一个名为DOM的方法,所有主要浏览器都支持该方法,该方法将使元素与视口的顶部/左侧对齐(或尽可能靠近)

    在受支持的浏览器上,您可以提供以下选项:

    $("#myImage")[0].scrollIntoView({
        behavior: "smooth", // or "auto" or "instant"
        block: "start" // or "end"
    });
    
    或者,如果所有元素都有唯一的ID,您只需更改对象的
    散列
    属性即可获得后退/前进按钮支持:

    $(document).delegate("img", function (e) {
        if (e.target.id)
            window.location.hash = e.target.id;
    });
    
    之后,只需将
    scrollTop
    /
    scrollLeft
    属性调整-20:

    document.body.scrollLeft -= 20;
    document.body.scrollTop -= 20;
    
    看看这个插件。这是一个例子

    这个插件有很多选项,超出了你所能提供的范围。例如,您可以将滚动设置为平滑,然后在滚动结束时设置回调


    你也可以看看。

    既然你想知道它是如何工作的,我将一步一步地解释它

    首先,要将函数绑定为图像的单击处理程序:

    $('#someImage').click(function () {
        // Code to do scrolling happens here
    });
    
    这将对具有
    id=“someImage”
    的图像应用单击处理程序。如果要对所有图像执行此操作,请将
    '#someImage'
    替换为
    'img'

    现在查看实际的滚动代码:

  • 获取图像偏移(相对于文档):

  • 从顶部和左侧减去20:

    offset.left -= 20;
    offset.top -= 20;
    
  • 现在为
    的滚动顶部和滚动左侧CSS属性设置动画:


  • 有多种方法可以将图元直接滚动到视图中,但如果要从图元滚动到相对点,则必须手动执行此操作:

    在单击处理程序中,获取元素相对于文档的位置,减去
    20
    ,然后使用:

    var pos=$(this.offset();
    var top=位置top-20;
    左变量=左位置-20;
    滚动到((左<0?0:左),(顶<0?0:顶));
    
    我的UI在拇指条中有一个垂直滚动的拇指列表 目标是使当前拇指位于拇指条的中心。 我从认可的答案开始,但发现有一些调整可以真正使当前的拇指居中。希望这对其他人有帮助

    标记:

    <ul id='thumbbar'>
        <li id='thumbbar-123'></li>
        <li id='thumbbar-124'></li>
        <li id='thumbbar-125'></li>
    </ul>
    

    下面是一个快速jQuery插件,可以很好地映射内置浏览器功能:

    $.fn.ensureVisible = function () { $(this).each(function () { $(this)[0].scrollIntoView(); }); };
    
    ...
    
    $('.my-elements').ensureVisible();
    

    经过反复试验,我提出了这个函数,它也可以与iframe一起使用

    function bringElIntoView(el) {    
        var elOffset = el.offset();
        var $window = $(window);
        var windowScrollBottom = $window.scrollTop() + $window.height();
        var scrollToPos = -1;
        if (elOffset.top < $window.scrollTop()) // element is hidden in the top
            scrollToPos = elOffset.top;
        else if (elOffset.top + el.height() > windowScrollBottom) // element is hidden in the bottom
            scrollToPos = $window.scrollTop() + (elOffset.top + el.height() - windowScrollBottom);
        if (scrollToPos !== -1)
            $('html, body').animate({ scrollTop: scrollToPos });
    }
    
    函数bringElIntoView(el){
    var elOffset=el.offset();
    变量$window=$(window);
    var windowscorlbottom=$window.scrollTop()+$window.height();
    var scrollToPos=-1;
    if(elOffset.top<$window.scrollTop())//元素隐藏在顶部
    scrollToPos=elOffset.top;
    else if(elOffset.top+el.height()>windowScrollBottom)//元素隐藏在底部
    scrollToPos=$window.scrollTop()+(elOffset.top+el.height()-windowScrollBottom);
    如果(滚动地形!==-1)
    $('html,body').animate({scrollTop:scrollToPos});
    }
    
    只是一个提示。仅适用于firefox


    我见过的最简单的解决方案

    var offset = $("#target-element").offset();
    $('html, body').animate({
        scrollTop: offset.top,
        scrollLeft: offset.left
    }, 1000);
    

    向下滚动到末尾或底部的两个简单步骤

    步骤1:获取可滚动(对话)div的完整高度

    步骤2:使用值在可滚动(对话)div上应用scrollTop 在步骤1中获得

    var fullHeight = $('#conversation')[0].scrollHeight;
    
    $('#conversation').scrollTop(fullHeight);
    

    上述步骤必须应用于会话div上的每个附加。

    在尝试找到一个解决方案来处理每种情况后(滚动动画的选项,滚动到视图中后在对象周围填充,甚至在模糊的情况下(例如在iframe中)也能工作),我最终为此编写了自己的解决方案。因为当许多其他解决方案失败时,它似乎起作用,所以我想与大家分享一下:

    function scrollIntoViewIfNeeded($target, options) {
    
        var options = options ? options : {},
        $win = $($target[0].ownerDocument.defaultView), //get the window object of the $target, don't use "window" because the element could possibly be in a different iframe than the one calling the function
        $container = options.$container ? options.$container : $win,        
        padding = options.padding ? options.padding : 20,
        elemTop = $target.offset().top,
        elemHeight = $target.outerHeight(),
        containerTop = $container.scrollTop(),
        //Everything past this point is used only to get the container's visible height, which is needed to do this accurately
        containerHeight = $container.outerHeight(),
        winTop = $win.scrollTop(),
        winBot = winTop + $win.height(),
        containerVisibleTop = containerTop < winTop ? winTop : containerTop,
        containerVisibleBottom = containerTop + containerHeight > winBot ? winBot : containerTop + containerHeight,
        containerVisibleHeight = containerVisibleBottom - containerVisibleTop;
    
        if (elemTop < containerTop) {
            //scroll up
            if (options.instant) {
                $container.scrollTop(elemTop - padding);
            } else {
                $container.animate({scrollTop: elemTop - padding}, options.animationOptions);
            }
        } else if (elemTop + elemHeight > containerTop + containerVisibleHeight) {
            //scroll down
            if (options.instant) {
                $container.scrollTop(elemTop + elemHeight - containerVisibleHeight + padding);
            } else {
                $container.animate({scrollTop: elemTop + elemHeight - containerVisibleHeight + padding}, options.animationOptions);
            }
        }
    }
    
    函数ScrollInView如果需要($target,options){
    var options=options?选项:{},
    $win=$($target[0].ownerDocument.defaultView),//获取$target的窗口对象,不要使用“窗口”,因为该元素可能位于与调用该函数的元素不同的iframe中
    $container=选项。$container?选项。$container:$win,
    填充=选项。填充?选项。填充:20,
    elemTop=$target.offset().top,
    elemHeight=$target.outerHeight(),
    containerTop=$container.scrollTop(),
    //超过此点的所有内容仅用于获取容器的可见高度,这是准确执行此操作所必需的
    containerHeight=$container.outerHeight(),
    winTop=$win.scrollTop(),
    winBot=winTop+$win.height(),
    CONTAINERVIBLETOP=containerTopwinBot?winBot:containerTop+containerHeight,
    ContainerVibleHeight=ContainerVibleBottom-ContainerVibleTop;
    if(elemTopcontainerTop+CONTAINERVIABLE高度){
    //向下滚动
    if(options.instant){
    $container.scrollpop(elemTop+elemHeight-containerServiceHeight+padding);
    }否则{
    $container.animate({scrollTop:elemTop+elemHeight-containerVibleHeight+padding},options.animationOptions);
    }
    }
    }
    
    $target
    是一个jQuery对象,其中包含您希望在需要时滚动到视图中的对象

    选项
    (可选)可以包含在对象中传递的以下选项:

    options.$container
    -一个jQuery对象,指向$target的包含元素(换句话说,dom中带有滚动条的元素)。默认为包含$target元素的窗口,该窗口足够智能,可以选择iframe窗口。请记住在属性名称中包含$

    opt
    
    $.fn.ensureVisible = function () { $(this).each(function () { $(this)[0].scrollIntoView(); }); };
    
    ...
    
    $('.my-elements').ensureVisible();
    
    function bringElIntoView(el) {    
        var elOffset = el.offset();
        var $window = $(window);
        var windowScrollBottom = $window.scrollTop() + $window.height();
        var scrollToPos = -1;
        if (elOffset.top < $window.scrollTop()) // element is hidden in the top
            scrollToPos = elOffset.top;
        else if (elOffset.top + el.height() > windowScrollBottom) // element is hidden in the bottom
            scrollToPos = $window.scrollTop() + (elOffset.top + el.height() - windowScrollBottom);
        if (scrollToPos !== -1)
            $('html, body').animate({ scrollTop: scrollToPos });
    }
    
    var offset = $("#target-element").offset();
    $('html, body').animate({
        scrollTop: offset.top,
        scrollLeft: offset.left
    }, 1000);
    
    var fullHeight = $('#conversation')[0].scrollHeight;
    
    $('#conversation').scrollTop(fullHeight);
    
    function scrollIntoViewIfNeeded($target, options) {
    
        var options = options ? options : {},
        $win = $($target[0].ownerDocument.defaultView), //get the window object of the $target, don't use "window" because the element could possibly be in a different iframe than the one calling the function
        $container = options.$container ? options.$container : $win,        
        padding = options.padding ? options.padding : 20,
        elemTop = $target.offset().top,
        elemHeight = $target.outerHeight(),
        containerTop = $container.scrollTop(),
        //Everything past this point is used only to get the container's visible height, which is needed to do this accurately
        containerHeight = $container.outerHeight(),
        winTop = $win.scrollTop(),
        winBot = winTop + $win.height(),
        containerVisibleTop = containerTop < winTop ? winTop : containerTop,
        containerVisibleBottom = containerTop + containerHeight > winBot ? winBot : containerTop + containerHeight,
        containerVisibleHeight = containerVisibleBottom - containerVisibleTop;
    
        if (elemTop < containerTop) {
            //scroll up
            if (options.instant) {
                $container.scrollTop(elemTop - padding);
            } else {
                $container.animate({scrollTop: elemTop - padding}, options.animationOptions);
            }
        } else if (elemTop + elemHeight > containerTop + containerVisibleHeight) {
            //scroll down
            if (options.instant) {
                $container.scrollTop(elemTop + elemHeight - containerVisibleHeight + padding);
            } else {
                $container.animate({scrollTop: elemTop + elemHeight - containerVisibleHeight + padding}, options.animationOptions);
            }
        }
    }