В зависимости от того, что вам нужно для поддержки, вам нужно множество различных методов, чтобы определить, когда страница становится видимой.Изменения происходят из-за поставщика браузера, версии браузера, ОС, работающих в WebView / UIWebView / WKWebView и т. Д.
Вы можете просмотреть, какие события происходят, используя эту страницу .Я обнаружил, что для определения того, когда страница «просыпается» во всех комбинациях, мне нужно было зарегистрировать все следующие события:
- событие видимости окна
- событие фокуса окна
- событие окна просмотра страниц
- запуск таймера и проверка того, занял ли таймер намного больше времени, чем должно быть (таймеры переводятся в спящий режим iOS при переходе в спящий режим).Приложение, использующее UIWebView, не запускает событие visibilityChange даже на iOS9 (WKWebView в порядке).
Раньше я также использовал webkitRequestAnimationFrame, но я удалил это, потому что это может вызвать джанк (AFAIK движок рендеринга делает для него блокирующий вызов основного потока).
Вещипопробовать:
- Перейти на другую вкладку
- Экран блокировки, подождать, разблокировать
- Установить другое приложение на фокус
- Свернуть браузер
Вы можете увидеть, какие события происходят:
- в режиме реального времени, посмотрев журнал консоли (прикрепить отладчик).
- в режиме реального времени на устройстве с помощьюиспользуя http://output.jsbin.com/rinece#http://localhost:80/ и просмотрите журнал, запрошенный как вызовы Ajax (используйте прокси-сервер или запустите небольшой сервер по адресу после # и введите тело в консоль).
- посмотрите наЖурнал экрана и обратите пристальное внимание на время, зарегистрированное для каждой записи, чтобы увидеть, была ли запись зарегистрирована, например, событие скрытия visibilitychange может не произойти, когда страница действительно скрыта (если приложение находится в спящем режиме), но вместо этого ставится в очередь и происходит, когда страница перезапускается!!!
iOS: будьте осторожны, если вы используете таймер для определения того, перешел ли iOS UIWebView в спящий режим, вам нужно измерить разницу, используя new Date.getNow()
, а не performance.now()
.Это связано с тем, что performance.now()
перестает считать время, когда страница переводится в спящий режим, и iOS медленно реализует performance.now () ... (Кроме того: вы можете измерить количество времени, в течение которого страница спала, обнаруживразница между new Date.getNow()
и performance.now()
. Найдите! = на тестовой странице ).
Если вы используете UIWebView, то есть два метода, которые работают (вынеобходимо использовать UIWebView, если вы поддерживаете приложение iOS7).WKWebView имеет событие visibilitychange, поэтому обходные пути не требуются.
== Техника 1.
Когда в приложении происходит событие applicationWillEnterForeground, вызовите UIWebView stringByEvaluatingJavaScriptFromString, чтобы вызвать страницу JavaScriptAwakened ().
Преимущества: чистота, точность.
Недостаток: нужен код Objective-C.Вызываемая функция должна быть доступна из глобальной области видимости.
== Техника 2.
Используйте webkitRequestAnimationFrame и обнаруживать временную задержку.
Преимущества: только JavaScript.Работает для мобильного Safari на iOS7.
Недостаток: ужасный риск джанка и использования webkitRequestAnimationFrame - серьезный взлом.
// iOS specific workaround to detect if Mobile App comes back to focus. UIWebView and old iOS don't fire any of: window.onvisibilitychange, window.onfocus, window.onpageshow
function iosWakeDetect() {
function requestAnimationFrameCallback() {
webkitRequestAnimationFrame(function() {
// Can't use timestamp from webkitRequestAnimationFrame callback, because timestamp is not incremented while app is in background. Instead use UTC time. Also can't use performance.now() for same reason.
var thisTime = (new Date).getTime();
if (lastTime && (thisTime - lastTime) > 60000) { // one minute
// Very important not to hold up browser within webkitRequestAnimationFrame() or reference any DOM - zero timeout so shoved into event queue
setTimeout(pageAwakened, 0);
}
lastTime = thisTime;
requestAnimationFrameCallback();
});
}
var lastTime;
if (/^iPhone|^iPad|^iPod/.test(navigator.platform) && !window.indexedDB && window.webkitRequestAnimationFrame) { // indexedDB sniff: it is missing in UIWebView
requestAnimationFrameCallback();
}
}
function pageAwakened() {
// add code here to remove duplicate events. Check !document.hidden if supported
};
window.addEventListener('focus', pageAwakened);
window.addEventListener('pageshow', pageAwakened);
window.addEventListener('visibilitychange', function() {
!document.hidden && pageAwakened();
});