2

请检查我做了什么http://jsfiddle.net/dUVmh/1/

关于我想要实现的动画是:

当您第一次向下滚动页面时,窗口滚动到 #green DIV。之后,如果您再次向下滚动窗口滚动到 #yellow DIV 并且在向上滚动时相同(从#yellow 到#green)。

关于问题: 您可以看到它卡在#green DIV 上的动画。

$(window).scroll(function(){
    if($(this).scrollTop() > 0) {
        $("html, body").animate({ scrollTop: $('#green').offset().top }, 1000);
    }
    else if($(this).scrollTop() > 1000) {
        $("html, body").animate({ scrollTop: $('#yellow').offset().top }, 1000);
    }
    else{
         $("html, body").animate({ scrollTop: $('#red').offset().top }, 1000);
    }

});

我在JS方面没有太多经验。

谢谢我提前:)

4

2 回答 2

4

这是一个有趣的问题。

此解决方案将 div 放入数组中,并记住上次滚动到的元素的数组索引。一旦触发了滚动事件,它就会检查新的 scrollTop 是否高于或低于当前 div 的顶部偏移量,并相应地移动到数组中的下一个或上一个 div。

此解决方案允许您拥有许多 div。我试图消除滚动到快速时出现的闪烁,但我认为唯一的方法是在动画期间禁用滚动条。

http://jsfiddle.net/dUVmh/35/

$(function() {
    var divs = [],
        body = $('body, html'),
        currentDiv = 0,
        timeout;

    $('div').each(function() {
        divs.push($(this));
    });

    // we only need to capture the first scroll event triggered and then
    // add another listener once we have done our animation
    var scrollListen = function() {
        $(window).one('scroll', function() {
            doScroll($(this).scrollTop());
        });
    };

    // Without the timeout, the scroll event would be triggered again too soon
    var scrollEnd = function() {
        clearTimeout(timeout);
        timeout = setTimeout(function() {
            scrollListen();
        }, 10);
    };

    // checks if the scroll direction was up and down and animates
    // the body scrollTop to the next or previous div
    var doScroll = function(scrollTop) {
        var direction = scrollTop - divs[currentDiv].offset().top;

        if (direction > 0 && currentDiv + 1 < divs.length) {
            nextDiv = currentDiv + 1;
        } else if (currentDiv - 1 > -1) {
            nextDiv = currentDiv - 1;
        }

        if (currentDiv === nextDiv) {
            scrollEnd();
        }

        body.animate({
            scrollTop: divs[nextDiv].offset().top
        }, 1000, function() {
            currentDiv = nextDiv;
            scrollEnd();
        });
    };

    scrollListen();
});

编辑:Firefox scrollTop 需要在 html 而不是 body 上进行更改。还修复了 firefox 一次多次调用 scrollListen 的问题。

于 2013-01-01T12:46:30.020 回答
1

问题是在使用 jQuery$(window).scroll(function())滚动动画时会一遍又一遍地调用。ScrollTop

这是一个可能的解决方案,它检查它当前是否正在滚动并且只执行ScrollTop一次动画。

http://jsfiddle.net/dUVmh/29/

旁注:检查用户滚动的方向(向上或向下)并根据滚动到顶部或向下的下一个 div 可能是一个好主意。
您可以检查是否保存了最后一个 scrollTop 位置并将其与当前位置进行比较。

更新:这是一个考虑到滚动方向的解决方案:http: //jsfiddle.net/dUVmh/36/

于 2013-01-01T10:11:42.897 回答