Функция событий iOS 6 js не вызывается, если в ней есть setTimeout - программирование
Подтвердить что ты не робот

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

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

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

Например:

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

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

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

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

Спасибо

4b9b3361

Ответ 1

Примечание. Похоже, что UIWebView не поддерживает requestAnimationFrames. Спасибо Guillaume Gendre за то, что указали!

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

Для нас это было проблемой, вызвавшей проблемы. Мы применили обходное решение (найдено здесь: 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 по запросуAnimationFrame

Удачи!