2010-06-10 21 views
78

Intento hacer una página para ir a la página de inicio después de, por ejemplo. 10 segundos de inactividad (el usuario no hace clic en ningún lugar). Yo uso jQuery para el resto, pero el set/clear en mi función de prueba es javascript puro.setTimeout/clearTimeout problems

En mi frustation terminé con algo así como esta función que esperaba llamar en cualquier clic en la página. El temporizador comienza bien, pero no se restablece con un clic. Si la función se llama 5 veces en los primeros 10 segundos, a continuación, 5 alertas apear ... no clearTimeout ...

function endAndStartTimer() { 
    window.clearTimeout(timer); 
    var timer; 
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
} 

Cualquiera tiene algunas líneas de código que va a hacer el truco? - en cualquier clic, finalice y reinicie el temporizador. - Cuando el temporizador golpea, por ej. 10sec hacer algo.

Respuesta

177

Debe declarar el "temporizador" fuera de la función. De lo contrario, obtienes una nueva variable en cada invocación de función.

var timer; 
function endAndStartTimer() { 
    window.clearTimeout(timer); 
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
} 
+4

¡Gracias por ahorrarme una hora! –

14

Eso es porque el temporizador es una variable local para su función.

Intente crearlo fuera de la función.

43

El problema es que la variable timer es local y su valor se pierde después de cada llamada a la función.

Es necesario persistir, puede ponerlo fuera de la función, o si no quiere exponer a la variable como global, se puede almacenar en un closure, por ejemplo:

var endAndStartTimer = (function() { 
    var timer; // variable persisted here 
    return function() { 
    window.clearTimeout(timer); 
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
    }; 
})(); 
3

No seguro de si esto viola alguna regla buenas prácticas de codificación, pero me suelen salir con éste:

if(typeof __t == 'undefined') 
     __t = 0; 
clearTimeout(__t); 
__t = setTimeout(callback, 1000); 

este prevenir la necesidad de declarar el temporizador de la función.

EDITAR: esto tampoco declara una nueva variable en cada invocación, pero siempre recicle la misma.

Espero que esto ayude.

2

Una manera de utilizar esto en reacción:

class Timeout extends Component { 
    constructor(props){ 
    super(props) 

    this.state = { 
     timeout: null 
    } 

    } 

    userTimeout(){ 
    const { timeout } = this.state; 
    clearTimeout(timeout); 
    this.setState({ 
     timeout: setTimeout(() => {this.callAPI()}, 250) 
    }) 

    } 
} 

útil si desea sólo para llamar a una API después de que el usuario ha dejado de escribir por ejemplo. La función userTimeout podría vincularse mediante onKeyUp a una entrada.

+1

Esto es lo que he estado buscando en un par de horas, gracias. Me preguntaba si hay una mejor manera de que suceda este tipo de resultado. – nikasv

+1

@nikasv estrangulamiento, y el antirrebote son dos alternativas: https://medium.com/@_jh3y/throttling-and-debouncing-in-javascript-b01cad5c8edf –

+1

sin saber cómo lograr esto jugado es parte de no obtener una oferta de trabajo - por lo que conocer este enfoque se considera fundamental. –