Richard
Richard

Reputation: 7433

Scrolling up to the topmost in iOS's Safari causes problems with scrolling-up/down detection

I have the following Javascript code:

$(window).scroll(function() {
    if (window.innerWidth <= 768) {
        let scrollStatus = $(this).scrollTop();

        if (scrollStatus > lastScrollTop) {
            //do some stuffs

        else
            //do some other stuffs

        lastScrollTop = scrollStatus;
    }
});

So it worked well with non-mobile devices and Android devices. However, when I ran that on iOS's Safari and scroll to the topmost, it drags down the viewport by a little bit before bouncing up back when I release my finger hold. That bounce back up is detected by the above Javascript code as scrolling up and causes the trigger on the else section, which is undesirable. How do I fix this?

Upvotes: 1

Views: 1696

Answers (1)

Kolya
Kolya

Reputation: 385

Before bouncing back Safari overscrolls the Y-Position into negative land. You can use this to ignore position changes from the bounce animation.

The window scroll event fires very rapidly. For performance reasons you don't want to handle these events directly.

The example below shows how to check in 250ms intervals whether the user has scrolled, which is easy on performance.

var didScroll = false;

$(window).scroll(function() {
  didScroll = true;
});

// interval scroll handler
setInterval(function() {
  if ( didScroll ) {
    didScroll = false;
    scrolled();
  }
}, 250);

var lastScrollTop = 0;

function scrolled() {
  var scrollStatus = window.pageYOffset;

  if (scrollStatus < lastScrollTop) {
      //user scrolled up
  } else if ( lastScrollTop >= 0) {
      //user scrolled down
  }
  lastScrollTop = scrollStatus;
}

Alternatively you can alleviate performance issues by resetting a timeout that only calls the scrolled() function after scrolling has finished.

var timer;

$(window).scroll(function() {
  if ( timer ) clearTimeout(timer);
  timer = setTimeout(function(){
    scrolled();
  }, 100);
});

var lastScrollTop = 0;

function scrolled() {
  var scrollStatus = window.pageYOffset;

  if (scrollStatus < lastScrollTop) {
      //user scrolled up
  } else if ( lastScrollTop >= 0) {
      //user scrolled down
  }
  lastScrollTop = scrollStatus;
}

Upvotes: 1

Related Questions