2012-10-12 14 views
14

Zauważyłem to dziwne zachowanie w najnowszym iOS (iOS 6). W przypadku wywoływania funkcji dla dowolnego zdarzenia dotykowego, które ma w sobie wartość setTimeout, część wewnątrz parametru setTimeout nigdy nie jest wyzwalana.Funkcja zdarzeń iOS 6 js nie jest wywoływana, jeśli ma ona wartość setTimeout

Zdarza się to tylko w przypadku "animacji systemowej", takiej jak przewijanie i powiększanie/zmniejszanie.

Na przykład:

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

(użyłem jQuery tylko do testów, ale to samo dzieje się z czystych js)

otworzyć tę stronę z safari na dowolnym urządzeniu z iOS 6 i powiększyć lub pomniejszyć . Alert nigdy nie zostanie wywołany.

Testowany na dowolnym urządzeniu z systemem iOS 5 to działa dobrze! Wydaje się, że podczas tych animacji setTimeout lub setInterval są resetowane przez system operacyjny. Czy jest to zamierzone zachowanie lub błąd?

Dzięki

Odpowiedz

16

Uwaga: To wygląda jak UIWebView nie obsługuje requestAnimationFrames. Dzięki Guillaume Gendre za wskazanie go!

Wystąpił podobny problem z aplikacją internetową, nad którą pracujemy.

Dla nas to touchmove spowodowało problemy. Wdrożyliśmy obejście (znalezione tutaj: https://gist.github.com/3755461), które wydawało się działać całkiem dobrze, dopóki inny problem nie zmusił nas do jego porzucenia. (Próbowałem dodać obejście do skrzypiec i byłem w stanie uruchomić timer raz lub dwa razy, ale wymagało to dziwnego gestu + zdarzenia przewijania, które było prawie niemożliwe do konsekwentnego odtwarzania.)

W każdym razie, jeden z nowe funkcje w iOS 6 dla programistów to requestAnimationFrames. Moje obejście to w zasadzie opakowanie dla timerów, pozwalające programistce przekazać wartość logiczną, która wywoła funkcję macierzystą lub funkcję obejścia.

Na przykład

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

Tutaj są inne sposoby wykorzystujące rozwiązania:

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

tu dwa bawi się przykładach obejścia. Spróbuj pinch/powiększania na czarne kwadraty:

http://jsfiddle.net/xKh5m/embedded/result (Wykorzystuje natywne setTimeout funkcja) http://jsfiddle.net/ujxE3/embedded/result

Używamy tego obejścia przez kilka miesięcy w środowisku produkcyjnym, a nie napotkasz żadnych istotnych problemów .

Oto publicznych Istota rozwiązania: https://gist.github.com/4180482

Oto więcej informacji na temat requestAnimationFrames:

MDN documentation

Paul Irish on requestAnimationFrame

Powodzenia!

+0

dziękuję za bardzo szczegółową odpowiedź, ale jak już wspomniano, nie jest to właściwe rozwiązanie mojego problemu. Ale teraz myślę, że to błąd wprowadzony w iOS6, a nie jakaś nowa funkcja. – kiwi1342

+0

Wygląda jak rozwiązanie dla mnie. –

+1

To jest ogromne, na pewno mnie uratowało. Więcej osób musi zobaczyć to rozwiązanie. – eivers88

Powiązane problemy