Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit 'mousewheel' delta to fire once per scroll

I'm using the following code below, to scroll two divs in different directions () but I'm curious to know if you can limit the scroll so it only fires once per scroll (rather than it continually scrolling and sending my functions into an endless loop.

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

You can see where I'm up up to here: http://dev.rdck.co/lyonandlyon/

Thanks in advance, R

Animation functions for reference:

var prevProject = function() { // up arrow/scroll up
    var windowHeight = $(window).height();

    $('.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});
    });
    $('.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});
    });
};


var nextProject = function() { // down arrow/scroll down
    var windowHeight = $(window).height();

    $('.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});
    });
    $('.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});
    });
};
like image 614
John the Painter Avatar asked Jan 18 '14 21:01

John the Painter


2 Answers

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
};
like image 32
friedi Avatar answered Sep 20 '22 23:09

friedi


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();
    }
}) );
like image 180
Mottie Avatar answered Sep 18 '22 23:09

Mottie