iPhone/iPad 的 javascript 滚动事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2863547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javascript scroll event for iPhone/iPad?
提问by ck_
I can't seem to capture the scroll event on an iPad. None of these work, what I am doing wrong?
我似乎无法在 iPad 上捕获滚动事件。这些都不起作用,我做错了什么?
window.onscroll=myFunction;
document.onscroll=myFunction;
window.attachEvent("scroll",myFunction,false);
document.attachEvent("scroll",myFunction,false);
They all work even on Safari 3 on Windows.
Ironically, EVERY browser on the PC supports window.onload=if you don't mind clobbering existing events. But no go on iPad.
它们甚至可以在 Windows 上的 Safari 3 上运行。具有讽刺意味的是,window.onload=如果您不介意破坏现有事件,PC 上的每个浏览器都支持。但在 iPad 上不行。
回答by kennytm
The iPhoneOS does capture onscrollevents, except not the way you may expect.
iPhoneOS 确实会捕获onscroll事件,但不是您所期望的方式。
One-finger panning doesn't generate any events until the user stops panning—an
onscrollevent is generated when the page stops moving and redraws—as shown in Figure 6-1.
单指平移不会产生任何事件,直到用户停止平移——
onscroll当页面停止移动和重绘时生成一个事件——如图 6-1 所示。
Similarly, scroll with 2 fingers fires onscrollonly after you've stopped scrolling.
同样,onscroll只有在您停止滚动后才会使用 2 根手指滚动。
The usual way of installing the handler works e.g.
安装处理程序的常用方法例如
window.addEventListener('scroll', function() { alert("Scrolled"); });
// or
$(window).scroll(function() { alert("Scrolled"); });
// or
window.onscroll = function() { alert("Scrolled"); };
// etc
回答by George Filippakos
For iOS you need to use the touchmoveevent as well as the scrollevent like this:
对于 iOS,您需要像这样使用touchmove事件和滚动事件:
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
}
回答by Dave Mackintosh
Sorry for adding another answer to an old post but I usually get a scroll event very well by using this code (it works at least on 6.1)
很抱歉为旧帖子添加另一个答案,但我通常使用此代码可以很好地获得滚动事件(它至少在 6.1 上有效)
element.addEventListener('scroll', function() {
console.log(this.scrollTop);
});
// This is the magic, this gives me "live" scroll events
element.addEventListener('gesturechange', function() {});
And that works for me. Only thing it doesn't do is give a scroll event for the deceleration of the scroll (Once the deceleration is complete you get a final scroll event, do as you will with it.) but if you disable inertia with css by doing this
这对我有用。它唯一不做的是为滚动的减速提供滚动事件(一旦减速完成,您将获得最终的滚动事件,按照您的意愿去做。)但是如果您通过执行此操作禁用 css 惯性
-webkit-overflow-scrolling: none;
You don't get inertia on your elements, for the body though you might have to do the classic
你不会对你的元素产生惯性,虽然你可能不得不做经典的身体
document.addEventListener('touchmove', function(e) {e.preventDefault();}, true);
回答by Melinda Weathers
I was able to get a great solution to this problem with iScroll, with the feel of momentum scrolling and everything https://github.com/cubiq/iscrollThe github doc is great, and I mostly followed it. Here's the details of my implementation.
我能够用 iScroll 得到一个很好的解决这个问题的方法,有动量滚动的感觉和一切https://github.com/cubiq/iscrollgithub 文档很棒,我主要遵循它。这是我的实现细节。
HTML:I wrapped the scrollable area of my content in some divs that iScroll can use:
HTML:我将内容的可滚动区域包装在 iScroll 可以使用的一些 div 中:
<div id="wrapper">
<div id="scroller">
... my scrollable content
</div>
</div>
CSS:I used the Modernizr class for "touch" to target my style changes only to touch devices (because I only instantiated iScroll on touch).
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:I included iscroll-probe.js from the iScroll download, and then initialized the scroller as below, where updatePosition is my function that reacts to the new scroll position.
JS:我从 iScroll 下载中包含 iscroll-probe.js,然后按如下方式初始化滚动条,其中 updatePosition 是我对新滚动位置做出反应的函数。
# coffeescript
if Modernizr.touch
myScroller = new IScroll('#wrapper', probeType: 3)
myScroller.on 'scroll', updatePosition
myScroller.on 'scrollEnd', updatePosition
You have to use myScroller to get the current position now, instead of looking at the scroll offset. Here is a function taken from http://markdalgleish.com/presentations/embracingtouch/(a super helpful article, but a little out of date now)
您现在必须使用 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};
}
The only other gotcha was occasionally I would lose part of my page that I was trying to scroll to, and it would refuse to scroll. I had to add in some calls to myScroller.refresh() whenever I changed the contents of the #wrapper, and that solved the problem.
唯一的其他问题是偶尔我会丢失我试图滚动到的页面的一部分,并且它会拒绝滚动。每当我更改#wrapper 的内容时,我都必须添加一些对 myScroller.refresh() 的调用,这解决了问题。
EDIT: Another gotcha was that iScroll eats all the "click" events. I turned on the option to have iScroll emit a "tap" event and handled those instead of "click" events. Thankfully I didn't need much clicking in the scroll area, so this wasn't a big deal.
编辑:另一个问题是 iScroll 吃掉了所有的“点击”事件。我打开了让 iScroll 发出“点击”事件并处理这些事件而不是“点击”事件的选项。谢天谢地,我不需要太多点击滚动区域,所以这没什么大不了的。
回答by Matthias Bohlen
Since iOS 8 came out, this problem does not exist any more. The scroll event is now fired smoothly in iOS Safari as well.
自从iOS 8出来后,这个问题就不存在了。滚动事件现在也可以在 iOS Safari 中顺利触发。
So, if you register the scrollevent handler and check window.pageYOffsetinside that event handler, everything works just fine.
因此,如果您注册scroll事件处理程序并检查window.pageYOffset该事件处理程序内部,则一切正常。


