【问题标题】:Scrolling up to the topmost in iOS's Safari causes problems with scrolling-up/down detection在 iOS 的 Safari 中向上滚动到顶部会导致向上/向下滚动检测问题
【发布时间】:2019-01-29 18:41:58
【问题描述】:

我有以下 Javascript 代码:

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

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

        else
            //do some other stuffs

        lastScrollTop = scrollStatus;
    }
});

因此它适用于非移动设备和 Android 设备。但是,当我在 iOS 的 Safari 上运行它并滚动到最顶部时,它会将视口向下拖动一点,然后在我松开手指时弹回。上述 Javascript 代码在向上滚动时检测到反弹,并导致触发 else 部分,这是不可取的。我该如何解决这个问题?

【问题讨论】:

    标签: javascript ios safari


    【解决方案1】:

    在弹回之前,Safari 会将 Y 位置过度滚动到负地。您可以使用它来忽略反弹动画的位置变化。

    窗口滚动事件触发得非常快。出于性能原因,您不想直接处理这些事件。

    下面的例子展示了如何以 250ms 为间隔检查用户是否滚动,这很容易提高性能。

    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;
    }
    

    或者,您可以通过重置仅在滚动完成后调用 scrolled() 函数的超时来缓解性能问题。

    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;
    }
    

    【讨论】:

    • 我明白了!我还怀疑延迟是由我的滚动脚本引起的。谢谢你指出。你认为我的resize 脚本也应该setInterval 吗?
    • 那么lastScrollTop 的初始值呢?还是0
    • 是的,lastScrollTop 应该初始化为 0,请参阅我的编辑。我不确定你的调整大小脚本做了什么,但如果它是通过滚动触发的,那么是的。
    • 抱歉,我所说的“调整大小”是指$(window).resize(function() { //do something });
    • 又学到了新东西:setTimeout :-D 谢谢!比setInterval还要好。
    猜你喜欢
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多