【问题标题】:How can I monitor scroll position while scrolling in Safari on iOS?如何在 iOS 上的 Safari 中滚动时监控滚动位置?
【发布时间】:2012-02-10 09:28:45
【问题描述】:

我目前使用$(window).bind('scroll', foo); 来监控$(window).scrollTop() 并做一些事情来创建视差效果。

在所有桌面浏览器中,用户滚动的每个像素都会调用foo(),一切都很好。在 iOS 上的 Safari 中,滚动事件仅在滚动完成后触发。

我添加了$(window).bind('touchmove', foo); 以确保在 iOS 中滑动期间调用该函数,这让我更进一步。当用户松开手指时,页面继续滚动,但事件停止触发。

有什么想法吗?

【问题讨论】:

    标签: javascript ios safari dom-events parallax


    【解决方案1】:

    当我看到你的问题时,我正计划为此做一个 polyfill(如果不存在的话?)。不幸的是,我的时间很少。

    这个想法是有一个setInterval,它被启动ontouchstart,它检查document.body.scrollTop自上次以来是否发生了变化,例如。每 20 毫秒。如果是,那么我们手动调度滚动事件。否则我们clearInterval,因为显然没有更多的滚动发生。

    这将是简短的。如果您有更多时间(比我多),请随意尝试这些指南。

    编辑:现在,进一步阅读,似乎在另一个答案中提出了相同的想法。您确定在 iPad 上滚动时间隔会停止吗?

    【讨论】:

    • 我在hakoniemi.net/labs/onscroll.html 尝试了同样的方法,结果得到了相同的分辨率:iOS 弹性滚动无法被跟踪。它没有事件监听器+滚动期间超时/间隔都不会执行。而且由于iOS5中没有requestAnimationFrame,这似乎是无法解决的。
    • 如果间隔运行失败,您当然不会期望 rAF 运行。但是,FWIW 可以在动量滚动进行时在基于 Web 套接字的 Safari 开发工具中获得最新读数。
    • 嘿,我们可以处理touchmove,而不是setInterval,这可能对berformace不利
    • 确实,滚动时似乎没有执行间隔。
    【解决方案2】:

    我强烈推荐使用“Skrollr”javascript 库。这是迄今为止我发现的最好的移动滚动动画选项,并且很容易快速启动和运行。根据开始和结束滚动位置创建动画和操作 CSS。为大多数标准 CSS 属性创建尽可能多的数据滚动位置和动画。

    在以下示例中,背景颜色将在 500 像素滚动过程中进行动画处理:

    <div data-0="background-color:rgb(0,0,255);" data-500="background-color:rgb(255,0,0);">WOOOT</div>
    

    在 Git 上签出存储库:https://github.com/Prinzhorn/skrollr

    Skrollr 演示示例:http://prinzhorn.github.io/skrollr/

    真棒现实世界示例:http://www.fontwalk.de/03/

    【讨论】:

    • 感谢您的参考。我正在处理同样的问题,希望 skrollr 能提供帮助,但是通过阅读我已经对此充满信心的很棒的文档。
    【解决方案3】:

    Apple 的 iPhone 5c 网页使用了一些视差滚动效果,似乎在您的手指仍触摸屏幕并滚动时会继续。所以我猜想在滚动期间不能完全禁用javascript。 Tumult Hype 也提供此功能。

    【讨论】:

      【解决方案4】:

      虽然这不可能开箱即用,但可以这么说,您可以使用 iscroll 来做到这一点

      因此,您可以将 iScroll 用于 iOS 和 Android 移动设备/平板电脑,并使用您目前在桌面设备上使用的方式。

      iScroll 有许多选项可用于在某些事件上调用回调函数 - 例如“onScrollMove”、“onBeforeScrollEnd”、“onTouchEnd”等。不幸的是,没有选项可以在“每次位置变化”时执行回调,包括用户停止触摸屏幕后滚动动量引起的变化”。但是,添加一个很容易。

      在 iScroll 源代码中,在第 127 行附近,靠近“//Events”注释,添加一个新变量:

      onPosChange: null
      

      然后,在第 308 行附近,在“_pos”函数的末尾,添加以下行:

      if (this.options.onPosChange) this.options.onPosChange.call();
      

      (如果存在,它将只调用“onPosChange”选项中传递的函数)。

      完成后,以下示例代码将为 id="iscroll_container" 的 div 设置 iScroll,并在每次更改时将 Y 偏移量打印到控制台:

      var myScroll;
      function loaded() {
          myScroll = new iScroll('iscroll_container', { onPosChange: actOnScroll });
      }
      
      document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
      
      //Use this for high compatibility (iDevice + Android)
      document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
      
      function actOnScroll(){
          console.log('got a scroll move! Vert offset is: ' + myScroll.y);
      }
      

      注意,Ben the Bodyguard Parallax Site 使用 iScroll 在 iPad 上工作(他们使用的是旧版本的 iscroll,并且不完全按照我在此处描述的方式进行操作)

      另外,Life of Pi Parallax Site 在 iPad 上运行得非常好 - 我不知道他们是如何做到的,但至少证明这是可能的!

      【讨论】:

        【解决方案5】:

        这可能是 jQuery 本身的错误:http://bugs.jquery.com/ticket/6446

        该票证已经开放了一段时间并且与 iOS 4 相关,但也许您应该研究使用纯 javascript 计算滚动位置。

        【讨论】:

          【解决方案6】:

          据我所知,在大多数移动设备上滚动时不会执行 javascript。 那里有一些解决方法(例如 iscroll)。 Iscroll 正在使用 css 技术“转换”。 但是滚动时无法执行javascript。 我想平滑滚动算法太贵了。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-10-31
            相关资源
            最近更新 更多