Div scrolling freezes sometimes if I use -webkit-overflow-scrolling

Adem picture Adem · Sep 26, 2016 · Viewed 17k times · Source

if I use -webkit-overflow-scrolling for a scrolling div, it scrolls perfectly with native momentum. But, div itself sometimes freezes and does not respond my finger moves. After 2-3 seconds later, it becomes again scrollable.

I don't know how I am reproducing this problem. But, as I see there are two main behavior creates this situation.

First, If I wait for a while, for instance, 20 seconds, and touch the div, it does not respond. I wait a couple of seconds, and it becomes working again.

Second, I touch several times quickly, and then, it becomes freezing, and again, after a couple of seconds later, it starts working again.

How can I prevent this freezing?

Answer

Wesley Reitzfeld picture Wesley Reitzfeld · Aug 7, 2018

For me, the freezing was repeatable and happened when trying to scroll up or down when already at the top or bottom, respectively. The fix was to add some listeners for touchstart and touchmove and detect these cases and event.preventDefault() on ’em.

Something like the following, where .scroller is the div that will actually scroll (changes to scrollTop).

var lastY = 0; // Needed in order to determine direction of scroll.
$(".scroller").on('touchstart', function(event) {
    lastY = event.touches[0].clientY;
});

$('.scroller').on('touchmove', function(event) {
    var top = event.touches[0].clientY;

    // Determine scroll position and direction.
    var scrollTop = $(event.currentTarget).scrollTop();
    var direction = (lastY - top) < 0 ? "up" : "down";

    // FIX IT!
    if (scrollTop <= 0 && direction == "up") {
      // Prevent scrolling up when already at top as this introduces a freeze.
      event.preventDefault();
    } else if (scrollTop >= (event.currentTarget.scrollHeight - event.currentTarget.outerHeight()) && direction == "down") {
      // Prevent scrolling down when already at bottom as this also introduces a freeze.
      event.preventDefault();
    }

    lastY = top;
});

I hope this helps the next poor soul that encounters this horrible bug! Good luck and keep fighting!