How to enforce a “smooth scrolling” rule for mousewheel, jQuery?

What I wanted to do was to simulate browser’s smooth scrolling on browsers that don’t support it natively, has it turned off by default or has bad implementation of it.

Thanks to lumbric’s answer I’ve came up with this solution:

$(function () {

    var top = 0,
        step = 55,
        viewport = $(window).height(),
        body = $.browser.webkit ? $('body') : $('html'),
        wheel = false;


    $('body').mousewheel(function(event, delta) {

        wheel = true;

        if (delta < 0) {

            top = (top+viewport) >= $(document).height() ? top : top+=step;

            body.stop().animate({scrollTop: top}, 400, function () {
                wheel = false;
            });
        } else {

            top = top <= 0 ? 0 : top-=step;

            body.stop().animate({scrollTop: top}, 400, function () {
                wheel = false;
            });
        }

        return false;
    });

    $(window).on('resize', function (e) {
        viewport = $(this).height();
    });

    $(window).on('scroll', function (e) {
        if (!wheel)
            top = $(this).scrollTop();
    });

});

Put some content on your page long enough to have scrollbars. Then use your mouse wheel. It works on every browser. I’ve used jQuery-1.7.2 and the mousescroll plugin mentioned in the lumbric’s post.

The step var means how many pixels to scroll on every mouse wheel event. ~55 pixels is what I’ve found to be the default value on most systems.

Also you may want to change the speed for the animation, other than that the rest of the code logic is needed to get the things work properly.

EDIT: Note that I have extracted the above functionality into a convenience jquery plugin.

Leave a Comment