14

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

仅当存在诸如滚动和放大/缩小之类的“系统动画”时才会发生这种情况。

例如:

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

(我使用 jquery 只是为了测试,但纯 js 也会发生同样的情况)

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

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

谢谢

4

1 回答 1

19

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

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

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

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

例如:

setTimeout(function(){alert("HI")}, 1000); // using native
setTimeout(function(){alert("HI")}, 1000, true); // using workaround

以下是使用该解决方法的其他方法:

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

这是解决方法示例的两个小提琴。尝试在黑色方块上捏合/缩放:

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

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

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

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

MDN 文档

Paul Irish on requestAnimationFrame

祝你好运!

于 2012-10-17T00:03:16.523 回答