iPhone / iPad的JavaScript滚动事件?


107

我似乎无法在iPad上捕获滚动事件。这些工作都没有,我做错了什么?

window.onscroll=myFunction;

document.onscroll=myFunction;

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

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

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

Answers:


146

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


23
谢谢,这迫使我进一步研究这个问题。真正的答案是检测iphone / ipad上的视口顶部是否只能使用 window.pageYOffset ,而 document.body.scrollTop||document.documentElement.scrollTop 不像现有的其他浏览器/硬件那样工作。
ck_

6
IPAD window.pageYOffset上的@ck_不幸的是,在减速阶段不会更新,而仅在滚动完成时才会更新。
Adaptabi 2013年

2
直接覆盖window.onscroll是一个不好的做法。添加事件监听器会更好。使用window.addEventListener('scroll',function(){alert('scrolled!');});
Kevin Dice 2014年

4
嗯..实际上,window.onscroll现在一直在我的ipad上射击,同时平移,平移后以及减速时。有什么变化吗?
commonpike 2015年

Safari(可能还有其他)更改为在iOS 8上使用WKWebView。Chrome和Cordova仍使用UIWebView,因此它们仍会出现连续滚动事件未发出的问题。不过,有一个用于Cordova的WKWebView插件。
jiku,2015年

105

对于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
}

37
仅当用户正在主动滚动时才触发此事件,而在动量滚动的减速阶段不触发该事件。
乔恩·蒂尔森

我更改了代码,使其包含iOS的结束滚动检测代码
George Filippakos 2012年

您可能还想为“ touchend”添加一个侦听器,其作用类似于在桌面上滚动。
BingeBoy 2014年

1
请注意,这并不提供滚动期间的访问权限
Ben Sewards 2015年

3
已经三年了 减速期间无法实时更新滚动位置。我应该如何编写类似地图的应用?
FlavorScape '16

38

抱歉,为旧帖子添加了另一个答案,但是使用此代码通常可以很好地实现滚动事件(至少在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);

7
为什么要否决有效答案而不发表评论来解释问题所在?
戴夫·麦金托什

3
因为投票容易而又快捷。:/
Zeshan Ahmed

5
根据其作者的说法,答案始终是“有效的” ...没有人发布已知为无效的答案。但是,是的,他们应该已经解释了为什么投票失败。
Matthieu Charbonnier16年

3
gesturechange事件是非标准的,并且仅受Safari支持:developer.mozilla.org/en-US/docs/Web/Events/gesturechange
Nicolas Bouvrette

6

我可以通过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,然后按如下所示初始化了滚动器,其中up​​datePosition是我对新滚动位置做出反应的函数。

# 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发出“ tap”事件并处理这些事件而不是“ click”事件的选项。值得庆幸的是,我不需要在滚动区域中单击太多,因此这没什么大不了的。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.