Limit 'mousewheel' delta to fire once per scroll

只谈情不闲聊 提交于 2019-12-05 06:57:47

You can just check for animation within the mousewheel function (demo)

$('.page-left, .page-right').on('mousewheel', function(event, delta) {
    if ($('.page-left-wrapper, .page-right-wrapper').is(':animated') ) {
        return false;
    }
    var windowHeight = $(window).height();
    if (delta < 0) {
        prevProject();
    }
    if (delta > 0) {
        nextProject();
    }
});

Update: we resolved to use debounce as the long scroll (sliding a finger down a touchpad) needed to be stopped (updated demo).

$(document).keydown( $.debounce( 250, function(e) {
    switch (e.which) {
    case 38: // up arrow
        prevProject();
        break;
    case 40: // down arrow
        nextProject();
        break;
    }
}) );

$('.page-left, .page-right').on('mousewheel', $.debounce( 250, function(event, delta) {
    var windowHeight = $(window).height();
    if (delta < 0) {
        prevProject();
    }
    if (delta > 0) {
        nextProject();
    }
}) );

You can get around this problem with a flag. You can use a global flag isAnimating and set it to true, if you are currently animating the position of the divs of your website.

So the code can look something like this:

var isAnimating = false;

$('.page-left, .page-right').bind('mousewheel', function(event, delta) {
    // if the div will be animated at this moment return
    if(isAnimating) {
        return;
    }

    var windowHeight = $(window).height();
    if (delta < 0) {
        prevProject();
    }
    if (delta > 0) {
        nextProject();
    }
});

var prevProject = function() {
    isAnimating = true;

    var oneIsDone = false,
        finish = function() {
            // if both animations are done, set the flag to false
            if(oneIsDone) {
                isAnimating = false;
            }
            // at least one is done...
            oneIsDone = true;
        };

    // animate the previous project and set the flag to false (in the callback)
    $('.page-left .page-left-wrapper').css({bottom:'auto'});
    $('.page-left .page-left-wrapper').animate({top:0},800, function() {
        $('.page-left .page-left-wrapper').prepend($('.page-left .project-left:last-of-type'));
        $('.page-left .page-left-wrapper').css({top:-windowHeight});
        finish();
    });
    $('.page-right .page-right-wrapper').css({top:'auto'});
    $('.page-right .page-right-wrapper').animate({bottom:+windowHeight*2},800, function() {
        $('.page-right .page-right-wrapper').append($('.page-right .project-right:first-of-type'));
        $('.page-right .page-right-wrapper').css({bottom:+windowHeight});
        finish(); 
    });
};

var nextProject = function() {
    // the same as in the prevProject function, but only in the other direction
};

I suggest to detect extremums to fire the function:

var mw1 = 0;
var mw2 = 0;
var lock;
$(document).bind('mousewheel', function(evt) {
    var delta = evt.originalEvent.deltaY
    if(((delta > 0 && delta < mw2 && mw2 > mw1) || (delta < 0 && delta > mw2 && mw2 < mw1)) && !lock){
        console.log(mw1 + " " + mw2 + " " + delta)
        // call some function here
        lock = true;
        window.setTimeout(function(){
            lock = false;
        },200)
    }
    mw1 = mw2;
    mw2 = delta;
})

lock is actually should not be necessary but extremums sometimes are found more than once per scroll for some reason.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!