简体   繁体   English

iPhone/iPad 的 javascript 滚动事件?

[英]javascript scroll event for iPhone/iPad?

I can't seem to capture the scroll event on an iPad.我似乎无法捕获 iPad 上的滚动事件。 None of these work, what I am doing wrong?这些都不起作用,我做错了什么?

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.它们甚至都可以在 Windows 上的 Safari 3 上工作。 Ironically, EVERY browser on the PC supports window.onload= if you don't mind clobbering existing events.具有讽刺意味的是,如果您不介意破坏现有事件,PC 上的每个浏览器都支持window.onload= But no go on iPad.但是在 iPad 上没有 go。

The iPhoneOS does capture onscroll events, except not the way you may expect. iPhoneOS确实捕获了onscroll事件,除了你不期望的方式。

One-finger panning doesn't generate any events until the user stops panning—an onscroll event is generated when the page stops moving and redraws—as shown in Figure 6-1. 在用户停止平移之前,单指平移不会生成任何事件 - 当页面停止移动并重绘时会生成onscroll事件 - 如图6-1所示。

Similarly, scroll with 2 fingers fires onscroll only after you've stopped scrolling. 同样,滚动与2个手指触发onscroll你已经停止滚动之后。

The usual way of installing the handler works eg 安装处理程序的常用方法有效

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

(See also https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html ) (另请参阅https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html

For iOS you need to use the touchmove event as well as the scroll event 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
}

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

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/iscroll The github doc is great, and I mostly followed it. 我能够通过iScroll得到一个很好的解决方案来解决这个问题,感觉有动力滚动和所有内容https://github.com/cubiq/iscroll github doc很棒,而且我大部分都遵循它。 Here's the details of my implementation. 这是我实施的细节。

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

# 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. 您必须使用myScroller立即获取当前位置,而不是查看滚动偏移量。 Here is a function taken from http://markdalgleish.com/presentations/embracingtouch/ (a super helpful article, but a little out of date now) 这是一个来自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. 编辑:另一个问题是iScroll吃了所有的“点击”事件。 I turned on the option to have iScroll emit a "tap" event and handled those instead of "click" events. 我打开选项让iScroll发出“点击”事件并处理这些事件而不是“点击”事件。 Thankfully I didn't need much clicking in the scroll area, so this wasn't a big deal. 值得庆幸的是,我不需要在滚动区域点击太多,所以这不是什么大问题。

Since iOS 8 came out, this problem does not exist any more. 自iOS 8问世以来,这个问题不再存在。 The scroll event is now fired smoothly in iOS Safari as well. 滚动事件现在也可以在iOS Safari中顺利启动。

So, if you register the scroll event handler and check window.pageYOffset inside that event handler, everything works just fine. 因此,如果您注册scroll事件处理程序并检查该事件处理程序中的window.pageYOffset ,一切正常。

After some testing on the ios, I found that this is the way to go for ios and desktop, if you are not worried of that delay of 120ms on desktop.在对 ios 进行一些测试后,我发现这是 ios 和桌面的 go 的方式,如果您不担心桌面上的 120ms 延迟。 Works like a charm.奇迹般有效。

let isScrolling;   
document.addEventListener("scroll", () => {
  // Clear our timeout throughout the scroll
  window.clearTimeout( isScrolling );

  // Set a timeout to run after scrolling ends
  isScrolling = setTimeout(function() {

    // Run the callback
    console.log( 'Scrolling has stopped.' );

  }, 120);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM