jquerymousewheel

How to prevent page scrolling when scrolling a DIV element?


I have reviewed and tested the various functions for preventing the body ability to scroll whilst inside a div and have combined a function that should work.

$('.scrollable').mouseenter(function() {
    $('body').bind('mousewheel DOMMouseScroll', function() {
        return false;
    });
    $(this).bind('mousewheel DOMMouseScroll', function() {
        return true;
    });
});
$('.scrollable').mouseleave(function() {
    $('body').bind('mousewheel DOMMouseScroll', function() {
        return true;
    });
});

Any ideas, or better ways of doing this?


Solution

  • Update 2: My solution is based on disabling the browser's native scrolling altogether (when cursor is inside the DIV) and then manually scrolling the DIV with JavaScript (by setting its .scrollTop property). An alternative and IMO better approach would be to only selectively disable the browser's scrolling in order to prevent the page scroll, but not the DIV scroll. Check out Rudie's answer below which demonstrates this solution.


    Here you go:

    $( '.scrollable' ).on( 'mousewheel DOMMouseScroll', function ( e ) {
        var e0 = e.originalEvent,
            delta = e0.wheelDelta || -e0.detail;
    
        this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
        e.preventDefault();
    });
    

    Live demo: https://jsbin.com/howojuq/edit?js,output

    So you manually set the scroll position and then just prevent the default behavior (which would be to scroll the DIV or whole web-page).

    Update 1: As Chris noted in the comments below, in newer versions of jQuery, the delta information is nested within the .originalEvent object, i.e. jQuery does not expose it in its custom Event object anymore and we have to retrieve it from the native Event object instead.