Функция iOS 6 js events не вызывается, если в ней есть setTimeout

Я заметил это странное поведение с последней iOS (iOS 6). При вызове функции для любого события касания, которое имеет setTimeout внутри, часть внутри setTimeout никогда не запускается.

Это происходит только при наличии «системной анимации», такой как прокрутка и увеличение / уменьшение.

Например:

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

(Я использовал JQuery только для тестирования, но то же самое происходит с чистым JS)

Откройте эту страницу с помощью Safari на любом устройстве iOS 6 и увеличьте или уменьшите масштаб. Предупреждение никогда не будет вызвано.

При тестировании на любом устройстве iOS 5 это будет работать просто отлично! Кажется, что во время этих анимаций setTimeout или setInterval сбрасываются ОС. Это предполагаемое поведение или ошибка?

Спасибо

Ответы на вопрос(1)

Решение Вопроса

Запись: Похоже, что UIWebView не поддерживает requestAnimationFrames. БлагодаряГийом Жандр за то, что указал на это!

Мы столкнулись с похожей проблемой в веб-приложении, над которым мы работаем.

Для нас, это было 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

Пол ирландский по запросу AnimationFrame

Удачи!

 Abadaba03 окт. 2013 г., 04:55
Кажется, не работает в ios7
 Guillaume Gendre26 апр. 2013 г., 09:58
Здравствуй! в моем случае (setTimeout, который вообще не вызывался, когда webview был pullToRefresh-ed), первый работал (gist.github.com/ronkorving/3755461) но не второй (gist.github.com/jpattishall/4180482). Какую проблему вы встретили с первой?
 TaylorMac30 апр. 2014 г., 22:40
Ошибка сохраняется IOS7, и это исправление больше не работает
 eivers8827 февр. 2013 г., 01:38
Это огромно, избавило меня от головной боли наверняка. Больше людей должны увидеть это решение
 TaylorMac04 мая 2014 г., 21:38
Джек, только что проверил после нескольких коммитов, и теперь все работает. Извините за ложную тревогу!

Ваш ответ на вопрос