0

I am attempting to work with some scroll events and create a "snapping" effect to the top level sections of my page. I am successfully capturing everything and animating the scroll position and everything actually works, however, when I am testing for the scroll event, it is firing everytime my condition is met, so my scroll function gets called too many times. I'm wondering how to best unbind the scroll event if my condition is met(the mousewheel has moved/spun a certain amount). I'm checking for the amount scroll with the 'direction' var just after the $window.on function. Any help refactoring this or advice on how better to do tackle it is appreciated.

For the record, I'm using jquery, greensock and a greensock plugin called scrollTo.

$(function(){

var $window = $(window);        //Window object

var scrollTime = 1;             //Scroll time
var scrollDistance = 250;       //Distance. Use smaller value for shorter scroll and greater value for longer scroll

$window.on("mousewheel DOMMouseScroll", function(event){

    event.preventDefault();

    var delta = event.originalEvent.wheelDelta/120 || -event.originalEvent.detail/3;
    var direction = delta > .875 ? 'up' : delta < -.875 ? 'down' : 'stick';

    if ( direction == 'up' ) {
        // going up...
        var next = $('.section.visible').prev('.section');
        scroll(next);
    }
    else if ( direction == 'down' ) {
        // going down to china town...
        var next = $('.section.visible').next('.section');
        scroll(next);
    }

    function scroll(next) {
        // scroll the doc
        var scroll = next.position().top;

        TweenMax.to($window, scrollTime, {
            scrollTo : { y: scroll, autoKill:true },
                ease: Power3.easeOut,
                autoKill: true,
                overwrite: 5                            
            });

        // clean up classes
        $('.section.visible').removeClass('visible');
        next.addClass('visible');
    }

});
});
4

2 回答 2

1

答案似乎是反弹。我读过关于节流与去抖动的文章,但似乎并不认为它们中的任何一个都是答案。感谢 Arun P Johny,他让我开始使用似乎是一种节流方法。它最终使我得到了正确的答案。

于 2013-08-14T02:07:39.770 回答
0

在这种情况下,一个经过测试的解决方案是使用setTimeout(),在以下情况下,如果在 200 毫秒内发生两个事件,则取消第一个事件

$(function(){

    var $window = $(window);        //Window object

    var scrollTime = 1;             //Scroll time
    var scrollDistance = 250;       //Distance. Use smaller value for shorter scroll and greater value for longer scroll

    $window.on("mousewheel DOMMouseScroll", function(event){
        var $this = $(this);

        event.preventDefault();

        clearTimeout($this.data('scrolltimer'));

        var timer = setTimeout($.proxy(function(){
            var delta = event.originalEvent.wheelDelta/120 || -event.originalEvent.detail/3;
            var direction = delta > .875 ? 'up' : delta < -.875 ? 'down' : 'stick';

            if ( direction == 'up' ) {
                // going up...
                var next = $('.section.visible').prev('.section');
                scroll(next);
            }
            else if ( direction == 'down' ) {
                // going down to china town...
                var next = $('.section.visible').next('.section');
                scroll(next);
            }

            function scroll(next) {
                // scroll the doc
                var scroll = next.position().top;

                TweenMax.to($window, scrollTime, {
                    scrollTo : { y: scroll, autoKill:true },
                    ease: Power3.easeOut,
                    autoKill: true,
                    overwrite: 5                            
                });

                // clean up classes
                $('.section.visible').removeClass('visible');
                next.addClass('visible');
            }
        }, this), 200);
        $this.data('scrolltimer', timer)

    });
});
于 2013-08-13T03:49:15.180 回答