Как возобновить таймер 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();

Ответ 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() }

Поскольку в настоящее время у меня нет устройства для проверки этого, это только слепое предположение. Надеюсь, это сработает для вас.