【问题标题】:jQuery :in-viewport selector accuracyjQuery :in-viewport 选择器的准确性
【发布时间】:2013-11-15 15:47:39
【问题描述】:

我有一个容器,里面有多个<div>s,代表页面。当用户滚动浏览这些页面时,我想更新当前的页码标签。为此,我发现我可以使用 :in-viewport 选择器。我尝试关注这个example,并想出了这个jsFiddle:

http://jsfiddle.net/j2aet/

这似乎可行,但我确实有一个小问题。那就是当我向下滚动时,我当前的页码不会更改为“2”,直到第二个“图像”元素部分隐藏(在顶部),并且第 3 页部分可见。我希望它尽快更改为 2。请参阅此屏幕截图以了解我的意思,这是它变为“2”的时候:

http://imgur.com/l40ddBs

理想情况下,只要第二个“图像”元素是占多数的元素,我希望当前页码更改为“2”。例如,这是关于我希望当前页码更改为“2”的位置:

http://imgur.com/uKZRD4m(注意#2 是大多数人的看法)

随着我不断滚动,它似乎变得更糟了。在下一个屏幕截图中,当前页码仍然显示为 5,但第 5 幅图像根本看不到了!

http://imgur.com/tr10aoU

我有什么不同的方法可以达到这个效果吗?现在我只是将in:viewport 选择器与:first 选择器结合使用:

$('.item:in-viewport:first')

【问题讨论】:

    标签: javascript jquery scroll viewport


    【解决方案1】:

    您可以通过以下方法尝试在每个项目向上滚动时检查它们的位置。 它并不完美,而且代码更多,但希望这能帮助您提供一些想法。

    这是fiddle 示例,下面是代码。

    $container.off('scroll').on('scroll', function () {
        var top = $(this).offset().top;
    
        $(".item").each(function()
        {  
            var itemTop = $(this).offset().top;
            var itemBottom = $(this).offset().top + $(this).height(); 
            if(itemTop >= (top + 25) && itemTop <= (top + 50))
                $cp.html($(this).attr("page"));
            else if(itemBottom >= (top + 400) && itemBottom <= (top + 425))
                $cp.html($(this).attr("page"));
    
        });
    });
    

    【讨论】:

    • 我明白你的想法 - 但是我的页码会随着你的代码从 1 变为 4?
    【解决方案2】:

    这就是我最终的结果:

    $container.on('scroll', function () {
        // for each item in viewport, which one is in view the MOST?
        var diff = null;
        var num;
        $('.item:in-viewport').each(function(){
            var thisPage = $(this).attr("page");
            var thisTop = $(this).position().top;
    
            if(diff == null){
                diff = Math.abs(containerTop - thisTop);
                num = thisPage;
            } else {
                var temp = Math.abs(containerTop - thisTop);
                if(temp < diff) {
                    diff = temp;
                    num = thisPage;
                }
            }
        });
        diff = null;
        $cp.html(num);
    });
    

    http://jsfiddle.net/j2aet/1/

    我仍然可以使用:in-viewport 选择器,但我没有将它与:first 选择器结合使用,而是遍历视图中的每个项目并找出最靠近容器顶部的项目。可能有一种更有效的方法可以做到这一点,但现在可以使用。

    更新(性能):

    根据我发现的一个想法 here,我们可以选择仅在用户完成滚动至少半秒后更新页码:

    $container.on('scroll', function () {
        if(this.scrollTo) clearTimeout(this.scrollTo);
        this.scrollTo = setTimeout(function () { updatePageNumber();}, 500);
    });
    
    function updatePageNumber(){
        // for each item in viewport, which one is in view the MOST?
        var diff = null;
        var num;
        $('.item:in-viewport').each(function(){
            var thisPage = $(this).attr("page");
            var thisTop = $(this).position().top;
    
            if(diff == null){
                diff = Math.abs(containerTop - thisTop);
                num = thisPage;
            } else {
                var temp = Math.abs(containerTop - thisTop);
                if(temp < diff) {
                    diff = temp;
                    num = thisPage;
                }
            }
        });
        diff = null;
        $cp.html(num);
    }
    

    http://jsfiddle.net/j2aet/2/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-26
      • 1970-01-01
      • 2019-07-26
      • 2012-02-08
      • 1970-01-01
      • 2010-11-27
      • 2011-06-23
      相关资源
      最近更新 更多