La fonction des événements iOS 6 js n'est pas appelée si SetTimeout est activé

J'ai remarqué ce comportement étrange avec le dernier iOS (iOS 6). Si vous appelez une fonction pour n'importe quel événement tactile qui a un setTimeout à l'intérieur, la partie à l'intérieur de setTimeout n'est jamais déclenchée.

Cela se produit uniquement lorsqu'il existe une «animation système» telle que défiler et zoomer / sortir.

Par exemple:

Http://jsfiddle.net/p4SdL/2/

(J'ai utilisé jquery juste pour tester, mais il en va de même avec js pur)

Ouvrez cette page avec safari sur tout périphérique iOS 6 et faites un zoom avant ou arrière. L'alerte ne sera jamais appelée.

Si testé sur un périphérique iOS 5, cela fonctionnera très bien! Il semble que pendant ces animations, le setTimeout ou setInterval soit réinitialisé par le système d'exploitation. Est-ce le comportement prévu ou un bug?

Merci

Remarque : Il semble que UIWebView ne supporte pas la demandeAnimationFrames. Merci à Guillaume Gendre de l' avoir souligné!

Nous avons rencontré un problème similaire avec une application Web sur laquelle nous travaillons.

Pour nous, c'était un mouvement tactile qui a causé des problèmes. Nous avons mis en œuvre une solution de contournement (trouvée ici: https://gist.github.com/3755461 ) qui semblait bien fonctionner jusqu'à ce qu'une autre question nous oblige à l'abandonner. (J'ai essayé d'ajouter la solution de contournement à votre violon et j'ai pu retirer la minuterie une ou deux fois, mais cela nécessitait un geste étrange + événement de défilement qui était presque impossible à reproduire de façon constante.)

Quoi qu'il en soit, l'une des nouvelles fonctionnalités d'iOS 6 pour les développeurs est la demandeAnimationFrames. Ma solution de contournement est essentiellement une enveloppe pour les temporisateurs, ce qui permet au développeur de passer un boolean, qui appellera soit la fonction native, soit la fonction de contournement.

Par exemple:

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

Voici d'autres façons d'utiliser la solution de contournement:

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

Voici deux violons avec les exemples de contournement. Essayez de pincer / zoomer sur les carrés noirs:

http://jsfiddle.net/xKh5m/embedded/result (Utilise la fonction native setTimeout ) http://jsfiddle.net/ujxE3/embedded/result

Nous utilisons cette solution de rechange pendant quelques mois dans un environnement de production et nous n'avons rencontré aucun problème majeur.

Voici un élément public de la solution de contournement: https://gist.github.com/4180482

Voici plus d'informations sur requestAnimationFrames:

Documentation MDN

Paul Irish sur demandeAnimationFrame

Bonne chance!