Как возобновить таймер JavaScript в веб-приложении iOS8 после разблокировки экрана?
В iOS8 это веб-приложение HTML5 не возобновляет таймер js после того, как экран заблокирован, а затем разблокирован, если webapp был активным и запущен из значка рабочего стола. В iOS7 таймер продолжится в этой ситуации. Мне нужен таймер для продолжения после разблокировки экрана - какие-нибудь советы для достижения этого?
Примечание/Пожалуйста, сначала добавьте веб-приложение на рабочий экран, используя Safari "добавить на главный экран" с помощью кнопки совместного доступа. Запуск страницы внутри Safari не вызывает проблемы, описанной выше.
<html>
<head>
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>Test</title>
<script>
var tim;
function go() {
tim = window.setInterval(action, 1000);
}
function action() {
document.getElementById('x').innerHTML = new Date().getTime().toString();
}
</script>
</head>
<body onload="go()">
<div id="x"></div>
</body>
</html>
Ответы
Ответ 1
Решение, которое мы закончили, не затрагивает все сломанные функции после спящего режима в IOS8, а скорее просто ajax-запросы/setTimeout/setInterval/requestAnimationFrame и их соответствующие четкие функции.
Другие вещи, сломанные после спящего режима:
- -webkit-непрозрачность перехода вызывает недоступные области
- worker.postMessage, вызываемый при открытии клавиатуры, постоянно убивает всех WebWorkers
- Откат окна/панорамирование может убить всех веб-мастеров.
- события overflowchange/resize больше не работают. Вам нужно переработать любую логику, которая зависит от них.
Чтобы сделать полурабочее решение:
- Заменить setTimeout/setInterval/requestAnimationFrame/clearInterval/clearTimeout/cancelAnimationFrame. Все эти функции должны быть отправлены на веб-сайт, где веб-исполнитель будет соответствующим образом выполнять setTimeout/setInterval. Возможно, вам также понадобится настроить медлинизм для этих функций, но я не на 100% его необходимый.
- Переопределить XMLHttpRequest, чтобы при вызове send запрос выполнялся на веб-сайте.
- Создайте механизм паузы для всех веб-мастеров, чтобы основной поток мог определить, когда все веб-работники покраснели свои сообщения (в основном, необходимо, чтобы postMessage не вызывался на любого рабочего, пока клавиатура встала).
- Предотвращение появления клавиатуры на редактируемых элементах. После обнаружения события щелчка/щелчка на редактируемом элементе вам необходимо вручную вызвать функцию фокуса.
- Переопределить функцию фокусировки на редактируемые элементы, открывающие клавиатуру. Теперь Focus теперь вызовет функцию пауз рабочих. После того, как все рабочие приостановлены, вызовите фокус браузера.
- Добавить получателя события фокуса в редактируемые элементы, чтобы вызвать функцию возобновления работы.
У меня есть полу-абстрагированная версия на моем github, доступная для других. Мы используем версию github в нашей довольно сложной/большой и сильно анимационной + зависимой от ajax приложении с очень небольшим количеством проблем.
https://github.com/TaDaa/IOS8-FIX
Ответ 2
Установка iOS 8.1.1 устраняет эту проблему.
Ответ 3
Вот пример моего рабочего обходного пути.
Рабочий Script backgrond.js
setInterval(function () {
postMessage(JSON.stringify({
message: "tiktok",
result: new Date().getTime()
}));
}, 500);
Страница Script - отредактировал следующие комментарии 2014-10-30
var GUI = {
iOS8: false,
web_worker: null,
tik: new Date().getTime(),
tok: new Date().getTime(),
init: function(){
GUI.web_worker = new Worker("scripts/background.js");
GUI.web_worker.onmessage = function (event) {
var d = JSON.parse(event.data);
if (d.message === 'tiktok') {
GUI.tik = d.result;
if (Math.abs(GUI.tik - GUI.tok) > (15 * 1000) && GUI.iOS8 ) {
GUI.web_worker.terminate();
document.write('Please restart app after locking the screen. Apple are working to prevent this issue.');
}
};
}
setInterval(function () { GUI.tok = new Date().getTime(); }, 1000);
var ua = navigator.userAgent.toLowerCase();
GUI.iOS8 = ua.indexOf("os 8_0") !==-1 || ua.indexOf("os 8_1") !==-1;
}
}
GUI.init();
Ответ 4
Для другого обходного пути для запросов Ajax (включая работу с серверами), но он работает здесь: iOS 8 Bug - OnUpdateReady никогда не вызывается снова, когда устройство возвращается из сна
Ответ 5
Я попробовал исправление, и он не работает на моих iphone4 и IOS8.
Я нашел на своем телефоне версии Alert Box сбой приложения после того, как вы заблокировали его и вышли из него... В основном я поставил окно предупреждения. Это говорит, что PLease закрывает и перезапускает приложение, когда таймер установки перестает обновляться с помощью экрана onlclick... SOoo Messy... Это ужасная ошибка!
Ответ 6
Это было исправлено на iOS 8.1.3.
Я использую библиотеку EaselJS, которая использует requestAnimationFrame или setTimeout внутри для обновления тика. У этой проблемы была проблема с iOS 8.0.x, но она была исправлена на iOS 8.1.3.
Ответ 7
Предполагая, что каждый раз, когда телефон разблокирован, обрабатывается событие window.onload
, попробуйте следующее:
window.onload = function() { window.location.reload() }
Поскольку в настоящее время у меня нет устройства для проверки этого, это только слепое предположение. Надеюсь, это сработает для вас.