javascript - una - Cuando uso setInterval, si cambio las pestañas en Chrome y vuelvo, el control deslizante se vuelve loco poniéndose al día
modo kiosko chrome (6)
Algunas ideas vienen a la mente:
Idea n. ° 1
Puede hacer que una ráfaga corta sea idempotente . Por ejemplo, podrías decir:
function now() {
return (new Date()).getTime();
}
var autopagerInterval = 8000;
function startAutopager() {
var startImage = getCurrentImageNumber();
var startTime = now();
var autopager = setInterval(
function() {
var timeSinceStart = now() - startTime();
var targetImage = getCurrentImageNumber + Math.ceil(timeSinceStart/autopagerInterval);
if (getCurrentImageNumber() != targetImage)
setImageNumber(targetImage); // trigger animation, etc.
},
autopagerInterval
);
return autopager;
}
De esta forma, incluso si la función se ejecuta 1000 veces, aún se ejecutará en solo unos pocos milisegundos y se animará solo una vez.
nota : si el usuario abandona la página y vuelve, se habrá desplazado. Probablemente esto no sea lo que quiere el póster original, pero dejo esta solución ya que a veces es lo que quiere.
Idea # 2
Otra forma de agregar idempotencia (manteniendo la función nextImage()
y sin desplazarla al final de la página) sería que la función establezca un bloqueo mutex que desaparecerá después de un segundo (borrado por otro tiempo de espera). Por lo tanto, incluso si la función setInterval se llamara 1000 veces, solo se ejecutaría la primera instancia y las demás no harían nada.
var locked = false;
var autopager = window.setInterval(function(){
if (!locked) {
locked = true;
window.setTimeout(function(){
locked=false;
}, 1000);
nextImage();
}
}, 8000);
editar: esto puede no funcionar, ver a continuación
Idea n. ° 3
Intenté la siguiente prueba:
function f() {
console.log((new Date()) + window.focus());
window.setTimeout(f, 1000);
}
f();
Parece indicar que la función se está llamando cada segundo. Esto es extraño ... pero creo que esto significa que se están llamando a las devoluciones de llamada, pero que el generador de páginas se niega a actualizar la página de forma gráfica mientras la pestaña está desenfocada, retrasando todas las operaciones hasta que el usuario regrese, pero las operaciones siguen acumulando arriba.
Además, la función window.focus()
no dice si la ventana tiene foco; da enfoque a la ventana y, por lo tanto, es irrelevante.
Lo que queremos es probablemente esto: ¿cómo detectar cuándo una pestaña está enfocada o no en Chrome con Javascript? - Puede deshacer su intervalo cuando la ventana pierde el enfoque (desenfoque), y restablecerlo cuando gana el foco.
Tengo un control deslizante jQuery en mi sitio y el código que va a la siguiente diapositiva está en una función llamada nextImage. Usé setInterval para ejecutar mi función en un temporizador, y hace exactamente lo que quiero: ejecuta mis diapositivas en un temporizador. PERO, si voy al sitio en Chrome, cambio a otra pestaña y regreso, el control deslizante se ejecuta continuamente a través de las diapositivas hasta que ''alcanza''. ¿Alguien sabe de una manera de arreglar esto? El siguiente es mi código.
setInterval(function() {
nextImage();
}, 8000);
Me enfrenté a un problema similar, de alguna manera este código a continuación funciona bien para mí.
var t1= window.setInterval(''autoScroll()'', 8000);
window.addEventListener(''focus'', function() {
focused = true;
window.clearInterval(t1);
t1 = window.setInterval(''autoScroll()'', 8000);
},false);
window.addEventListener(''blur'', function() {
focused = false;
window.clearInterval(t1);
},false)
function autoScroll()
{
if ( running == true){
if ( focused = true){
forwardSlide();
}
}
else {
running = true;
}
}
No sé exactamente qué está sucediendo en su función nextImage (), pero tuve un problema similar. Estaba usando animate () con setInterval () en un control deslizante de imagen jQuery que creé, y estaba experimentando lo mismo que usted cuando cambié a una pestaña diferente y viceversa. En mi caso, la función animate () estaba en cola, por lo que una vez que la ventana recupera el foco, el control deslizante se volvería loco. Para solucionar esto, simplemente detuve la función animate () de la cola.
Hay un par de formas en que puedes hacer esto. el más fácil es con .stop (), pero este problema y las formas de solucionarlo están documentados en los documentos jQuery. Consulte esta página cerca de la parte inferior debajo del encabezado notas adicionales: http://api.jquery.com/animate/
Si está utilizando el control deslizante de imagen de Soh Tanaka, simplemente agregue esto ... para resolver su problema con Google Chrome:
$(".image_reel").stop(true, true).fadeOut(300).animate({ left: -image_reelPosition}, 500 ).fadeIn(300);
Tome nota de la función .stop (). Ignora el desvanecimiento de las cosas, eso es lo que usé en mi versión
Gracias
¿Cómo detectar cuándo una pestaña está enfocada o no en Chrome con Javascript?
window.addEventListener(''focus'', function() {
document.title = ''focused'';
},false);
window.addEventListener(''blur'', function() {
document.title = ''not focused'';
},false);
Para aplicar a su situación:
var autopager;
function startAutopager() {
autopager = window.setInterval(nextImage, 8000);
}
function stopAutopager() {
window.clearInterval(autopager);
}
window.addEventListener(''focus'', startAutopager);
window.addEventListener(''blur'', stopAutopager);
Tenga en cuenta que en la última versión de Chromium, existe un error o una ''característica'' que hace que esto sea menos confiable, lo que requiere que el usuario haya hecho clic al menos una vez en cualquier lugar de la ventana. Vea la pregunta vinculada arriba para más detalles.
Publiqué una respuesta aquí: ¿cómo puedo hacer que setInterval también funcione cuando una pestaña está inactiva en Chrome?
Solo haz esto:
setInterval(function() {
$("#your-image-container").stop(true,true);
nextImage();
}, 1000);
las pestañas inactivas del navegador almacenan algunas de las funciones setInterval o setTimeout. stop (true, true) - detendrá todos los eventos almacenados en el búfer y ejecutará immadietly solo la última animación.
El método window.setTimeout () ahora se bloquea para enviar no más de un tiempo de espera por segundo en pestañas inactivas. Además, ahora fija los tiempos de espera anidados al valor más pequeño permitido por la especificación HTML5: 4 ms (en lugar de los 10 ms que usó para fijar).