如果其中包含setTimeout,则不会调用iOS 6 js事件函数

kiw*_*342 14 javascript jquery html5 ios ios6

我注意到最新iOS(iOS 6)的这种奇怪行为.如果为任何内部具有setTimeout的触摸事件调用函数,则永远不会触发setTimeout内的部分.

仅当存在诸如滚动和放大/缩小的"系统动画"时才会发生这种情况.

例如:

http://jsfiddle.net/p4SdL/2/

(我使用jquery进行测试,但纯js也是如此)

在任何iOS 6设备上使用safari打开该页面并放大或缩小.永远不会调用警报.

如果在任何iOS 5设备上进行测试,这将正常工作!似乎在这些动画期间,操作系统会重置setTimeout或setInterval.这是预期的行为还是错误?

谢谢

Jac*_*ack 17

注意:看起来UIWebView不支持requestAnimationFrames.感谢Guillaume Gendre指出它!

我们遇到了一个与我们正在开发的网络应用程序类似的问题.

对我们来说,触摸它会导致问题.我们实施了一个解决方法(在这里找到:https://gist.github.com/3755461)似乎工作得很好,直到另一个问题迫使我们放弃它.(我尝试将解决方法添加到您的小提琴中,并且能够让计时器触发一次或两次,但它需要一个奇怪的手势+滚动事件,几乎不可能一致地重现.)

无论如何,iOS 6中为开发人员提供的新功能之一是requestAnimationFrames.我的解决方法基本上是计时器的包装器,允许开发人员传递一个布尔值,它将调用本机函数或变通方法函数.

例如:

setTimeout(function(){alert("HI")}, 1000); // using native
setTimeout(function(){alert("HI")}, 1000, true); // using workaround
Run Code Online (Sandbox Code Playgroud)

以下是使用此变通方法的其他方法:

setInterval(function(){console.log("Interval")}, 1000, true);

var timer = setTimeout(function(){ /* ... */ }, 60000, true);
clearTimeout(timer);

var interval = setInterval(someFunc, 10000, true);
if(someCondition) clearInterval(interval);
Run Code Online (Sandbox Code Playgroud)

以下是两个带有解决方法示例的小提琴.尝试捏合/缩放黑色方块:

http://jsfiddle.net/xKh5m/embedded/result(使用原生setTimeout函数) http://jsfiddle.net/ujxE3/embedded/result

我们已经在生产环境中使用此解决方法几个月,并且没有遇到任何重大问题.

以下是解决方法的公开要点:https://gist.github.com/4180482

以下是有关requestAnimationFrames的更多信息:

MDN文档

Paul Irish on requestAnimationFrame

祝好运!

  • Bug仍然存在IOS7,此修复程序不再有效 (2认同)