【问题标题】:javascript scroll event for iPhone/iPad?iPhone / iPad的javascript滚动事件?
【发布时间】:2011-02-21 06:08:18
【问题描述】:

我似乎无法在 iPad 上捕捉滚动事件。 这些都不起作用,我做错了什么?

window.onscroll=myFunction;

document.onscroll=myFunction;

window.attachEvent("scroll",myFunction,false);

document.attachEvent("scroll",myFunction,false);

它们甚至都可以在 Windows 上的 Safari 3 上运行。 具有讽刺意味的是,如果您不介意破坏现有事件,PC 上的每个浏览器都支持window.onload=。但在 iPad 上不行。

【问题讨论】:

    标签: javascript iphone ipad scroll onscroll


    【解决方案1】:

    iPhoneOS 确实捕获了onscroll 事件,但不是您可能期望的方式。

    在用户停止平移之前,单指平移不会生成任何事件——当页面停止移动并重新绘制时会生成onscroll 事件——如图 6-1 所示。

    同样,只有在您停止滚动后,用两根手指滚动才会触发 onscroll

    安装处理程序的常用方法例如

    window.addEventListener('scroll', function() { alert("Scrolled"); });
    // or
    $(window).scroll(function() { alert("Scrolled"); });
    // or
    window.onscroll = function() { alert("Scrolled"); };
    // etc 
    

    (另见https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html

    【讨论】:

    • 谢谢,这迫使我进一步研究这个问题。真正的答案是检测 iphone/ipad 上的视口顶部仅适用于 window.pageYOffset 而不是 document.body.scrollTop||document.documentElement.scrollTop 就像现有的所有其他浏览器/硬件一样。
    • @ck_ 不幸的是,IPAD 上的window.pageYOffset 在减速阶段不会更新,只有在滚动完成时才会更新。
    • 直接覆盖window.onscroll是不好的做法。添加一个事件监听器会更好。使用 window.addEventListener('scroll', function (){ alert('scrolled!'); });
    • ehm .. 实际上,window.onscroll 一直在我的 ipad 上触发,在平移时,平移后,减速时。有什么变化吗?
    • Safari(可能还有其他人)在 iOS 8 中更改为使用 WKWebView。Chrome 和 Cordova 仍然使用 UIWebView,因此它们仍然存在未发出连续滚动事件的问题。不过有一个适用于 Cordova 的 WKWebView 插件。
    【解决方案2】:

    对于 iOS,您需要像这样使用 touchmove 事件以及 scroll 事件:

    document.addEventListener("touchmove", ScrollStart, false);
    document.addEventListener("scroll", Scroll, false);
    
    function ScrollStart() {
        //start of scroll event for iOS
    }
    
    function Scroll() {
        //end of scroll event for iOS
        //and
        //start/end of scroll event for other browsers
    }
    

    【讨论】:

    • 此事件仅在用户主动滚动时触发,在动量滚动的减速阶段不会触发。
    • 我更改了代码以包含 iOS 的结束滚动检测代码
    • 您可能还想为“touchend”添加一个监听器,它的作用类似于在桌面上滚动。
    • 请注意,这不提供在滚动阶段的访问权限
    • 已经三年了。在减速期间我无法实时更新滚动位置。我应该如何编写类似地图的应用程序??????
    【解决方案3】:

    很抱歉为旧帖子添加另一个答案,但我通常使用此代码很好地获得滚动事件(它至少在 6.1 上有效)

    element.addEventListener('scroll', function() {
        console.log(this.scrollTop);
    });
    
    // This is the magic, this gives me "live" scroll events
    element.addEventListener('gesturechange', function() {});
    

    这对我有用。它唯一不做的就是为滚动的减速提供一个滚动事件(一旦减速完成,你会得到一个最终的滚动事件,按照你的意愿去做。)但是如果你通过这样做禁用css的惯性

    -webkit-overflow-scrolling: none;
    

    你不会对你的元素产生惯性,尽管你可能不得不做经典的身体

    document.addEventListener('touchmove', function(e) {e.preventDefault();}, true);
    

    【讨论】:

    • 为什么要对一个有效的答案投反对票,而不是发表评论来解释它的问题?
    • 因为降级投票既简单又快捷。 ://
    • 根据作者的说法,答案始终是“有效的”……没有人故意发布无效的答案。但是,是的,他们应该解释为什么他们投了反对票。
    • gesturechange events 是非标准的,只有 Safari 支持:developer.mozilla.org/en-US/docs/Web/Events/gesturechange
    【解决方案4】:

    我能够用 iScroll 很好地解决这个问题,感觉动量滚动和一切 https://github.com/cubiq/iscroll github 文档很棒,我主要关注它。这是我的实现细节。

    HTML: 我将内容的可滚动区域包裹在 iScroll 可以使用的一些 div 中:

    <div id="wrapper">
      <div id="scroller">
        ... my scrollable content
      </div>
    </div>
    

    CSS: 我将 Modernizr 类用于“触摸”,将我的样式更改仅针对触摸设备(因为我只在触摸时实例化 iScroll)。

    .touch #wrapper {
      position: absolute;
      z-index: 1;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      overflow: hidden;
    }
    .touch #scroller {
      position: absolute;
      z-index: 1;
      width: 100%;
    }
    

    JS: 我从 iScroll 下载中包含了 iscroll-probe.js,然后按如下方式初始化了滚动条,其中 updatePosition 是我对新滚动位置做出反应的函数。

    # coffeescript
    if Modernizr.touch
      myScroller = new IScroll('#wrapper', probeType: 3)
      myScroller.on 'scroll', updatePosition
      myScroller.on 'scrollEnd', updatePosition
    

    您现在必须使用 myScroller 来获取当前位置,而不是查看滚动偏移量。这是一个取自http://markdalgleish.com/presentations/embracingtouch/ 的函数(一篇非常有用的文章,但现在有点过时了)

    function getScroll(elem, iscroll) {   
      var x, y;
    
      if (Modernizr.touch && iscroll) {
        x = iscroll.x * -1;
        y = iscroll.y * -1;   
      } else {
        x = elem.scrollTop;
        y = elem.scrollLeft;   
      }
    
      return {x: x, y: y}; 
    }
    

    唯一的另一个问题是有时我会丢失我试图滚动到的页面的一部分,并且它会拒绝滚动。每当我更改#wrapper 的内容时,我都必须添加一些对 myScroller.refresh() 的调用,这解决了问题。

    编辑:另一个问题是 iScroll 会吃掉所有的“点击”事件。我打开了让 iScroll 发出“点击”事件并处理这些事件而不是“点击”事件的选项。谢天谢地,我不需要在滚动区域点击太多,所以这没什么大不了的。

    【讨论】:

      【解决方案5】:

      自从 iOS 8 出来后,这个问题就不再存在了。现在,滚动事件也可以在 iOS Safari 中顺利触发。

      因此,如果您注册scroll 事件处理程序并在该事件处理程序中检查window.pageYOffset,一切正常。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 2013-01-08
      相关资源
      最近更新 更多