javascript - debug - ¿Cómo detectar en la aplicación web de iOS al volver a Safari desde el fondo?
iphone safari debug (6)
Creo que los temporizadores (setInterval ()) se suspenden cuando la aplicación entra en segundo plano. Podrías hacer algo como:
var lastFired = new Date().getTime();
setInterval(function() {
now = new Date().getTime();
if(now - lastFired > 5000) {//if it''s been more than 5 seconds
alert("onfocus");
}
lastFired = now;
}, 500);
Es posible que deba ajustar esos intervalos de tiempo para satisfacer sus necesidades.
Pero, lo más probable, si ha sido lo suficientemente largo como para necesitar un safari de actualización (unos días), probablemente se volverá a cargar la página porque se ha quedado sin memoria.
¿Cómo puedo crear una página web que pueda monitorear cuando la página se enfoca, especialmente cuando Safari está en segundo plano y el usuario cambia Safari de nuevo a primer plano?
El siguiente código no activa el evento cuando se cambia a Safari en un iPhone
<html>
<head>
<script type="text/javascript">
window.onfocus = function() { alert("onfocus"); };
</script>
</head>
<body>
Main text
</body>
</html>
Según http://www.quirksmode.org/dom/events/index.html : Safari iPhone no dispara el evento cuando la ventana se enfoca.
Así que mi pregunta sigue siendo: ¿cómo detectar mediante el uso de javascript en una página web dentro de Safari para iPhone que la ventana recibe el enfoque?
Dado que el problema es con el safari móvil y es compatible con el evento popstate, puede usar este evento para detectar cuándo el usuario está de regreso
Dependiendo de lo que necesite admitir, necesita una variedad de técnicas diferentes para detectar cuándo una página se vuelve visible. Las variaciones se producen debido al proveedor del navegador, la versión del navegador, el sistema operativo, ejecutándose dentro de WebView / UIWebView / WKWebView, etc.
Puede ver qué eventos están ocurriendo al usar esta página . Descubrí que para detectar cuándo la página se "despierta" en todas las combinaciones que necesitaba para registrar todos los eventos siguientes:
- evento de visibilidad de la ventana
- evento de enfoque de ventana
- ventana show de evento
- iniciar un temporizador y ver si el temporizador demoró más de lo debido (los hornos se ponen en suspensión en iOS cuando se hibernan). Una aplicación que utiliza UIWebView no dispara el evento con la visibilidad cambia incluso en iOS9 (WKWebView está bien).
También solía usar webkitRequestAnimationFrame, pero lo eliminé porque podría causar jank (AFAIK, el motor de renderizado realiza una llamada de bloqueo al subproceso principal).
Cosas para probar:
- Ir a otra pestaña
- Bloquear pantalla, esperar, desbloquear
- Trae otra aplicación para enfocar
- Minimizar navegador
Puedes ver qué eventos están sucediendo:
- en tiempo real mirando el registro de la consola (adjunte el depurador).
- en tiempo real en un dispositivo utilizando http://output.jsbin.com/rinece#http://localhost:80/ y vea cómo se solicita el registro como llamadas Ajax (use un proxy o ejecute un pequeño servidor en la dirección) después del # y registre el cuerpo a la consola).
- mire el registro en pantalla y preste mucha atención al tiempo registrado para cada entrada para ver si la entrada se registró, por ejemplo, el evento hidechange hide puede no ocurrir cuando la página está realmente oculta (si la aplicación está en hibernación), pero en su lugar está en cola y ocurre cuando se vuelve a mostrar la página!
iOS: tenga cuidado si usa un temporizador para detectar si un iOS UIWebView se ha desactivado, debe medir la diferencia utilizando el new Date.getNow()
y no performance.now()
. Esto se debe a que performance.now()
deja de contar el tiempo en que la página se pone en suspensión y iOS tardó en implementar performance.now () ... (Aparte: puede medir la cantidad de tiempo que la página estuvo inactiva). detectando la discrepancia de diferencias para el new Date.getNow()
y performance.now()
. Busque el = = en la página de prueba ).
Si está utilizando UIWebView, hay dos técnicas que funcionan (debe usar UIWebView si es compatible con una aplicación iOS7). WKWebView tiene el evento visibilidadchange, por lo que no se requieren soluciones alternativas.
== Técnica 1.
Cuando ocurra el evento applicationWillEnterForeground en la aplicación, llame a UIWebView stringByEvaluatingJavaScriptFromString para llamar a su página de JavaScript Despertado ().
Beneficios: limpio, preciso.
Desventaja: necesita el código Objective-C. La función llamada debe ser accesible desde el ámbito global.
== Técnica 2.
Utilice webkitRequestAnimationFrame y detecte un retraso de tiempo.
Beneficios: solo JavaScript. Funciona para móviles Safari en iOS7.
Desventaja: el feo riesgo de jank y el uso de webkitRequestAnimationFrame es un ataque grave.
// 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();
});
La API de visibilidad de la página probablemente ofrecería una solución a este problema. Supongo que esta API aún no se ha implementado en Mobile Safari, al menos no he encontrado ninguna documentación para una implementación de iOS. Sin embargo, una implementación se ha comprometido con el troncal Webkit, por lo que existe la posibilidad de que sea compatible con futuras versiones de Mobile Safari.
Los eventos de enfoque y desenfoque en la ventana son buenos para detectar si el navegador va o no al fondo. Esto me funcionó en iOS8 Safari:
window.addEventListener("focus", function(evt){
console.log(''show'');
}, false);
window.addEventListener("blur", function(evt){
console.log(''hide'');
}, false);
Usa los eventos de pageshow
y pagehide
.
<script type="text/javascript">
window.addEventListener("pageshow", function(evt){
alert(''show'');
}, false);
window.addEventListener("pagehide", function(evt){
alert(''hide'');
}, false);
</script>