Возможно ли в JavaScript определить, когда экран выключен в браузерах Android и iOS?

Я отслеживал смехотворно высокие времена загрузки, о которых сообщил javascript моего приложения, и обнаружил, что Android (и iOS) приостанавливают выполнение некоторого JavaScript, когда окно находится в фоновом режиме или дисплей выключен.

В Android я обнаружил, что могу использовать события window.onfocus и onblur, чтобы определить, когда приложение переключается в фоновый режим (и выполнение js вскоре будет приостановлено, по крайней мере, для новых скриптов), но я не могу найти способ обнаружить когда экран включен или выключен. Это возможно?

(В Safari у меня были аналогичные результаты, за исключением того, что onfocus и onblur не срабатывали надежно.)


person Nathan Friedly    schedule 11.04.2013    source источник
comment
Не вызывает ли выключение и включение экрана события onblur и onfocus, учитывая, что Android обычно переходит на какой-то экран блокировки? Я думаю, что его отключение может привести к срабатыванию onblur, и, по крайней мере, его пробуждение сработает onblur (если его отключение не сработает), потому что Android вызывает экран блокировки, а затем, пройдя через экран блокировки, сработает onfocus так как вы переходите с экрана блокировки обратно в активное приложение. Я не эксперт по Android, но решил выкинуть эту мысль, если вы не проверили.   -  person ajp15243    schedule 12.04.2013
comment
Ну, у меня не было, когда я тестировал его, но теперь, когда вы упомянули об этом, я отключил свой экран блокировки. Он просто возвращается к последнему приложению, которое я открывал, как только я нажимаю кнопку питания. Включение экрана блокировки вызывало срабатывание событий фокусировки и размытия. Спасибо!   -  person Nathan Friedly    schedule 12.04.2013


Ответы (4)


Есть несколько вариантов проверить это:

  1. Использование API видимости

  2. Использование событий focus и blur для определения видимости вкладки браузера:

window.addEventListener("focus", handleBrowserState.bind(context, true));
window.addEventListener("blur", handleBrowserState.bind(context, false));

function handleBrowserState(isActive){
    // do something
}
  1. Использование таймеров, как упоминалось выше
person Dmytro Medvid    schedule 13.09.2016
comment
Ха, первоначальный вариант спецификации Page Visibility был опубликован примерно через месяц после того, как я задал вопрос! На данный момент это кажется правильным ответом. - person Nathan Friedly; 13.09.2016
comment
3 года на получение правильного ответа :) Я сейчас работаю над теми же вопросами и уже получил много новой информации ... Но у меня все еще есть некоторые проблемы с интернет-браузером Android (на основе Chromium 34) - этот браузер не не обрабатывает изменения видимости, и ни один из описанных выше способов не работает... - person Dmytro Medvid; 14.09.2016

Я только что нашел довольно хорошее решение для моего варианта использования:

function getTime() {
    return (new Date()).getTime();
}

var lastInterval = getTime();

function intervalHeartbeat() {
    var now = getTime();
    var diff = now - lastInterval;
    var offBy = diff - 1000; // 1000 = the 1 second delay I was expecting
    lastInterval = now;

    if(offBy > 100) { // don't trigger on small stutters less than 100ms
        console.log('interval heartbeat - off by ' + offBy + 'ms');
    }
}

setInterval(intervalHeartbeat, 1000);

Когда экран выключен (или JS приостановлен по какой-либо причине), следующий интервал откладывается до тех пор, пока выполнение JS не возобновится. В моем коде я могу просто настроить таймеры на величину offBy и назвать это хорошим.

При быстром тестировании оказалось, что это хорошо работает как в браузере Android 4.2.2, так и в Safari на iOS 6.1.3.

person Nathan Friedly    schedule 11.04.2013

Нашел здесь хорошую функцию:

http://rakaz.nl/2009/09/iphone-webapps-101-detecting-essential-information-about-your-iphone.html

(function() {
    var timestamp = new Date().getTime();

    function checkResume() {
        var current = new Date().getTime();
        if (current - timestamp > 4000) {
            var event = document.createEvent("Events");
            event.initEvent("resume", true, true);
            document.dispatchEvent(event);
        }
        timestamp = current;
    }

    window.setInterval(checkResume, 1000);
})();   

Для регистрации на мероприятие:

addEventListener("resume", function() {
    alert('Resuming this webapp');
});

Это согласуется с Cordova, которая также запускает событие resume.

person Dunc    schedule 25.02.2016

что вы будете делать в своем сценарии после того, как экран выключится? В любом случае, вы можете внедрять объекты Java ( http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String) ) для взаимодействия с активность и прокси всю необходимую информацию в мире JS.

person comeGetSome    schedule 11.04.2013
comment
Не то, что я хочу делать, но вы получили положительный ответ, потому что это хороший ответ на вопрос :) - person Nathan Friedly; 12.04.2013