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

Posted

技术标签:

【中文标题】如果其中有 setTimeout,则不会调用 iOS 6 js 事件函数【英文标题】:iOS 6 js events function not called if has setTimeout in it 【发布时间】:2012-10-12 08:31:21 【问题描述】:

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

只有在有滚动和放大/缩小等“系统动画”时才会发生这种情况。

例如:

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

(我使用 jquery 只是为了测试,但纯 js 也是如此)

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

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

谢谢

【问题讨论】:

【参考方案1】:

注意: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 documentation

Paul Irish on requestAnimationFrame

祝你好运!

【讨论】:

感谢您非常详细的回答,但正如您所提到的,这不是解决我问题的正确方法。但现在,我认为这是iOS6中引入的一个bug,而不是什么新功能。 对我来说似乎是一个解决方案。 这是巨大的,肯定让我头疼。更多人需要看到这个解决方案 嗨!在我的情况下(当 webview 被 pullToRefresh-ed 时根本没有调用 setTimeout)第一个工作(gist.github.com/ronkorving/3755461)但不是第二个(gist.github.com/jpattishall/4180482)。第一个遇到了什么问题? Jack,在几次提交后刚刚重新测试,现在一切似乎都正常了。抱歉误报!

以上是关于如果其中有 setTimeout,则不会调用 iOS 6 js 事件函数的主要内容,如果未能解决你的问题,请参考以下文章

如果将点击手势识别器添加到其背景视图中,则不会调用 iOS didSelectItemAtIndexPath

如果我在 iOS 8 中更改 topviewcontroller 的方向,则不会调用 NavigationController willRotateToInterfaceOrientation

在 iOS 上,如果主视图具有 UITapGestureRecognizer,则不会调用按钮操作。如何让它发挥作用?

请简述一下settimeout和setinterval的区别,其中包括内存方面的分析前端

如果在片段和活动中都定义了 onRequestPermissionsResult,则不会在片段中调用

定时器 setTimeout()超时调用和 setInterval()间歇调用