René Wolferink
René Wolferink

Reputation: 3548

Prevent scrolling when done too quickly with jQuery

In order to prevent mousewheel scrolling to scroll the entire page when reaching the top/bottom of an element with its own scrollbars, I'm using Brandon Aaron's Mousewheel plugin.

This works fine, as long as I don't scroll too quickly. It seems that when scrolling really quickly, two events will pass the "I haven't reached the top/bottom" check yet and will both be executed. However, one of them will then scroll the element to the top/bottom and the next one will then scroll the entire page, which was what I was trying to prevent.

I'm currently doing this

$('.popupContents').bind('mousewheel', function (e, d) {
    var t = $(this);
    if (d > 0 && t.scrollTop() === 0) {
        e.preventDefault();
    } else if (d < 0 && (t.scrollTop() == t.get(0).scrollHeight - t.innerHeight())) {
         e.preventDefault();
    }
});

(As posted in Prevent scrolling of parent element? )

How do I make it so that the function properly stops all events at the top/bottom even when the user scrolls quickly?

Upvotes: 1

Views: 1976

Answers (1)

Ren&#233; Wolferink
Ren&#233; Wolferink

Reputation: 3548

I ended up manually tracking the desired scroll position and disallowing the normal scroll event altogether.

var wantedScrollTop = 0;
$('.popupBody').bind('mousewheel', function (e, d) {
    var t = $(this);
    var scrollTo;
    if (d > 0) {
        scrollTo = Math.max(0, wantedScrollTop - 30);
    } else if (d < 0) {
        scrollTo = Math.min(t.get(0).scrollHeight - t.innerHeight(), wantedScrollTop + 30);
    }
    if (typeof scrollTo !== "undefined") {
        wantedScrollTop = scrollTo;
        t.scrollTop(wantedScrollTop);
        //t.stop().animate({ scrollTop: wantedScrollTop + 'px' }, 150);
    }
    e.preventDefault();
});

d is the scroll direction, so I'm manually keeping track of the wanted scroll position here. In my case there is only one popup at a time, so I didn't bother sticking the wantedScrollTop in a data- attribute or something similar on the element, which could be useful when youdo have multiple elements that need to track their own scroll position.

It is not doing a fluent scroll like your browser would, but it will change the vertical scroll position by 30 pixels for each time the scrollwheel triggers the event. I left the commented out line in the code to show how that could be achieved. However, for me this resulted in scrolling which feeled very lagged when scrolling quickly.

Upvotes: 1

Related Questions