Search code examples
jquerymousewheel

jQuery mouse wheel plugin customization


I have a fullscreen slider and want to enable to navigation using a mouse wheel. To detect an mouse wheel event I thought the jQuery mousewheel plugin should be the best option.

I am able to include it and fire functions. But I am not able (and did not find any resources) to configure it the way I want.

I want to check for a certain amount of scrolled pixels. So, if for example, the mouse wheel try to scroll 20px up, I want to fire a function, or 20px down for another function.

​$(document).ready(function(){
    $('body').bind('mousewheel', function(e){
        if(e.originalEvent.wheelDelta /120 > 0) {
            alert('Wait! I fire way too often!');
        }
        else{
            alert('We are going down, way too msuch alerts!');
        }
    });
});

JS FIDDLE (Scroll Up/Down)


Solution

  • If I understand your problem correctly, you're seeing the events fire too often. The issue here is that for any given scroll action, the event fires several times. You can see this if you open the developer console in your browser and do a console.log(e.originalEvent.wheelDelta). This can break a large scroll into several small scroll events, throwing off your desired behavior. The way I handled this was to use a variable to hold the scroll delta:

    $(document).ready(function(){   
        var scrollPixels = 0; // variable to store scroll delta
    
        $('body').bind('mousewheel', function(e){
            // increment/decrement scroll delta
            scrollPixels += e.originalEvent.wheelDelta;
            console.log(scrollPixels);
    
            if (scrollPixels < -20) {
                scrollPixels = 0; // clear scroll delta
                alert('Coming down!');
            }
            else if (scrollPixels > 20){
                scrollPixels = 0; // clear scroll delta
                alert('Coming up!');
            }
        });
    });
    

    You can then clear the scroll delta after either up or down alert fires.

    JS Fiddle

    You may also want to increase your test to more than 20 pixels as most scrolls will fire this event - 20 pixels is only about 1/4 of an inch.

    Hope that helps. If that doesn't fix your issue, feel free to comment on where I went wrong. Best of luck!


    Update to address comment:

    You can wait until the scroll stops by setting a timeout that will wait a short amount of time (250 ms in this example) after scrolling has stopped executing. I moved the logic inside this timeout so that it will only run after scrolling has stopped:

    $(document).ready(function(){   
        var scrollPixels = 0; // variable to store scroll delta
        var scrolling; // timeout function var
    
        $('body').bind('mousewheel', function(e){
            // increment/decrement scroll delta
            scrollPixels += e.originalEvent.wheelDelta;
            console.log(scrollPixels);
    
            clearTimeout(scrolling);
            scrolling = setTimeout(function() {
            console.log('stop wheeling! ', scrollPixels);
            scrolling = undefined;
    
            if (scrollPixels < -300) {
                scrollPixels = 0; // clear scroll delta
                alert('Coming down!');
            }
            else if (scrollPixels > 300){
                scrollPixels = 0; // clear scroll delta
                alert('Coming up!');
            }
    
      }, 250);
        });
    });
    

    Updated JS Fiddle