【问题标题】:Jquery scroll to next/prev div with same classJquery滚动到具有相同类的下一个/上一个div
【发布时间】:2015-01-20 17:37:48
【问题描述】:

我有几个 div,都具有相同的类(帖子),并且我有一个简单的向上和向下导航。

<nav>
<a href="" id="down">Down</a>
<a href="" id="up">Up</a>
</nav>

<div class="post one">Lorem ipsum dolor sit amet.</div>
<div class="post two">Lorem ipsum dolor sit amet.</div>
<div class="post three">Lorem ipsum dolor sit amet.</div>

每次用户点击向下时,我都想向下滚动一个 div。每次用户点击向上时,我都想向上一个 div。

我几乎明白了,但是如果您单击两次然后又想再次向上两次,则会出现一些错误,然后滚动条卡在中间。此外,如果您位于最底部并再次单击“向下”,它会从顶部开始。此外,如果您单击一个向上和一个向下,则滚动它不符合应有的逻辑。

请看这里http://jsfiddle.net/grovve/bs6443y4/

我假设它与我的变量“$currentElement”有关,并且在给定时间这个变量的确切值是什么,对吗?我究竟缺少什么让它按应有的方式工作?

【问题讨论】:

    标签: jquery


    【解决方案1】:

    您收到错误的原因很简单——如果您位于列表的底部(即最后一个元素),$currentElement.next() 将不会返回任何内容。当您处于顶部时,也会发生类似的事情。因此,您应该使用if 在触发点击处理程序时检查下一个或上一个元素是否存在。我们可以使用.length 来评估这个条件。

    同时,您可能想查看using .stop() before actually adding another animation to the queue。如果你不使用它,你最终会在每次鼠标点击时向 jQuery 动画队列中添加太多的项目,这是我们不希望的——这可能会导致动画不流畅或动画需要很长时间才能完成。因此,我们在每个动画前面调用.stop(true)来清空整个队列。

    最后,当我们使用.prev().next() 遍历DOM 时,我们接受所有 元素——所以我们应该分别包含选择器,即.prev('.post').next('.post')实现所需的行为。

    var $currentElement = $(".post").first();
    
    $("#down").click(function () {
        var $nextElement = $currentElement.next('.post');
        // Check if next element actually exists
        if($nextElement.length) {
            // If yes, update:
            // 1. $currentElement
            // 2. Scroll position
            $currentElement = $nextElement;
            $('html, body').stop(true).animate({
                scrollTop: $nextElement.offset().top
            }, 1000);
        }
        return false;
    });
    
    $("#up").click(function () {
        var $prevElement = $currentElement.prev('.post');
        // Check if previous element actually exists
        if($prevElement.length) {
            // If yes, update:
            // 1. $currentElement
            // 2. Scroll position
            $currentElement = $prevElement;
            $('html, body').stop(true).animate({
                scrollTop: $prevElement.offset().top
            }, 1000);
        }
        return false;  
    });
    

    在此处查看更新和工作小提琴:http://jsfiddle.net/teddyrised/bs6443y4/7/

    【讨论】:

    • 很好的一个检查是否有下一个元素并清除动画队列。
    • 谢谢你,你的 cmets 说得通。我看到的问题不是它没有进入第三个 div,它只是停留在 1 和 2 之间。你知道这是为什么吗?
    • @user2089160 我似乎无法复制您的问题。我正在使用 Chrome 39,像往常一样导航到最后一个 div(绿色)...
    • 当你点击第一个div时,它会转到第二个div
    • 你是对的。我再次刷新了浏览器,它可以工作了。非常感谢您的帮助,非常感谢!
    【解决方案2】:

    看一下up函数中的注释。您在那里使用了 var,因此您处于错误的范围内。

    var $currentElement = $(".post").first();
    
    $("#down").click(function () {
        $currentElement = $currentElement.next();
        $('html, body').animate({
            scrollTop: $currentElement.offset().top
        }, 1000);
        return false;
    });
    
    $("#up").click(function () {
        /* here's your problem! the var tells js to only use currentElement in this function not globally, the variable on the first line isn't overwritten!
        var currentElement = $currentElement.prev();
        to fix it simply remove the var! */
        $currentElement = $currentElement.prev();
        $('html, body').animate({
            scrollTop: $currentElement.offset().top
        }, 1000);
        return false;  
    });
    

    【讨论】:

    • 还是错了,前面需要$符号。另请参阅上面的额外逻辑以防止滚动,否则会引发错误。
    • @PatrickRoberts 是的。我错过了。我现在已经对其进行了调整,但我建议使用 Terri 提出的方法,因为它会检查是否有下一个元素。
    • 我的为什么不像提供的示例那样左右滚动? jsfiddle.net/k66gLuLk/3 我在页面加载时对 div 进行排序。谢谢
    【解决方案3】:

    如果您希望向上/向下从下到上包裹帖子,请尝试从 Terry 的答案分叉的代码:

    var $currentElement = $(".post").first();
    
        $("#down").click(function () {
            var currentElement = $currentElement.next(".post");
            // Check if next element actually exists
            if(currentElement.length) {
                // If yes, update:
                // 1. $currentElement
                // 2. Scroll position
                $currentElement = currentElement;
            } else {
                $currentElement = currentElement = $(".post").first();
            }
    
            $('html, body').stop(true).animate({
                scrollTop: $(currentElement).offset().top
            }, 1000);
            return false;
        });
    
        $("#up").click(function () {
            var currentElement = $currentElement.prev(".post");
            // Check if previous element actually exists
            if(currentElement.length) {
                // If yes, update:
                // 1. $currentElement
                // 2. Scroll position
                $currentElement = currentElement;
            } else {
                $currentElement = currentElement = $(".post").last();
            }
    
            $('html, body').stop(true).animate({
                scrollTop: $(currentElement).offset().top
            }, 1000);
            return false;
        });
    

    在此处查看演示:http://jsfiddle.net/bs6443y4/8/

    【讨论】:

    • 我的为什么不像提供的示例那样左右滚动? jsfiddle.net/k66gLuLk/3 我在页面加载时对 div 进行排序。谢谢
    猜你喜欢
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多