2010-11-30 16 views
9

¿Cuál es la mejor forma de incorporar el objeto de evento al usar setTimeout? Estoy usando jQuery para gestionar la normalización del modelo de eventos en todos los navegadores, pero no estoy seguro de cómo colocar el objeto 'e' en la función checkPos.llamada de función Javascript setTimeout con argumento de evento?

Mi código actual:

function MouseDownEvent(e) { 
    *snip* 
    timeoutID = setTimeout(checkPos(e), 500); 
} 
function checkPos(e) { 
    //function uses e on a timeout of 500ms 
    timeoutID = setTimeout(checkPos(e) }, 500); 
} 

Actualmente funciona una vez que el código ya que la función se llama en el evento MouseDown, pero nunca actualiza el objeto electrónico cuando el usuario mueve el ratón. La consola de error de JavaScript de FF también declara que se trata de una llamada a setTimeout inútil (¿falta de comillas alrededor del argumento?), Pero seguir ese consejo hace que falle por completo.

¿Cómo puedo obtener el argumento del evento 'e' de una llamada a setTimeout?

Editar: Se ha añadido en el código que vuelve a ejecutar las checkPos funcionan cada 500 ms

+1

con su código, en realidad estás invocando '' checkPos' al llamar setTimeout' (debido a que el operador función de invocación '()') y pasando su valor de retorno a ' setTimeout'; ese valor probablemente no sea una referencia a una función, por lo que 'setTimeout' falla. –

Respuesta

7

En primer lugar, ¿por qué está utilizando dos tiempos de espera? A mi me parece como setInterval() sería mejor

function MouseDownEvent(e) { 
*snip* 
clearInterval(intervalID); 
intervalID = setInterval(function(){checkPos(e);}, 500); 
} 

En segundo lugar Podrían aclarar esto: "... pero nunca actualiza el objeto electrónico cuando el usuario mueve el ratón." ¿Por qué el objeto de evento se actualizará cuando el usuario mueva el mouse? Solo has asignado un manejador de MouseDown. Si quisiera hacer algo con cada movimiento del mouse, debería usar un evento mouseMove, en cuyo caso el tiempo de espera/intervalo sería innecesario de todos modos.

function MouseMoveEvent(e) { 
//called every time the mouse is moved, event object will contain position 
} 

Como siempre en JavaScript, primero debe buscar una solución impulsada por eventos y solo usar controladores temporizados cuando sea absolutamente necesario.

* Editar - op abordar las cuestiones planteadas en las observaciones *

var handler = { 
    i : 0, 
    function : mouseMoveEvent(e) { 
     handler.i++; 
     if (handler.i % 100 == 0) { 
     //Do expensive operations 
     } 
    } 
} 

$(myElement).bind("mousemove", handler.mouseMoveEvent); 
10

Probar:

function MouseDownEvent(e) { 
    *snip* 
    timeoutID = setTimeout(function(){checkPos(e);}, 500); 
} 
function checkPos(e) { 
    //function uses e on a timeout of 500ms 
} 

edición debido a los comentarios OP ..

Para tener acceso a un evento actualizado cada vez que se activa el checkPos:

var myNamespace = {}; 

$('body').mousemove(function(e) { 
    myNamespace.mouseEvent = e; 
}); 

function checkPos() { 
    doSomethingWith(myNamespace.mouseEvent); 
} 

timerID = setInterval(checkPos, 500); 
+0

Lamento haber retrocedido en esta respuesta, pero cuando volví a ejecutar este código, puse checkPos (e); en, no pudo traer el evento e actualizado después de cada tiempo de espera. –

+0

No funcionará con su código editado. Este método forma un 'cierre' sobre 'e'. Para acceder a un evento actualizado, debe almacenar el evento en algún lugar que sea accesible para la función 'checkPos' (externa a él), y actualice ese evento almacenado en la función' MouseDownEvent'. – sje397

+0

No hay forma de llamar al objeto de evento en javascript o jQuery de manera que pueda obtener la posición actual del mouse en función del tiempo de espera? –

1

Puede usar una función de curry, hay una para jQuery here.

general, que la presente:

function foo(a, b) 
{ 
    alert(a + b); 
} 

var bar = curry(foo, 1); 

bar(2); // alerts 3, as if you had called foo(1, 2) 

por lo que podría hacer:

setTimeout(curry(checkPos, e), 500); 

Desde el curry devuelve una función con su primer argumento unido a E, puede pasar directamente a setTimeout .

1

Por lo que pude ver, IE no permita que pase el "evento" objeto alrededor como que necesita.

La única solución que puedo pensar es almacenar el valor que necesita de antemano como variable global y luego verificar esa variable en la función de retraso.

Por ejemplo: http://jsfiddle.net/YvYtn/1/

Esto mostrará la última posición X, puede almacenar lo que necesita del objeto de evento.

El código JS:

var _lastPosX= null; 
function MouseDownEvent(evt) { 
    if (typeof evt == "undefined" || !evt) 
     evt = window.event; 
    _lastPosX = (evt.clientX || evt.pageX); 
    timeoutID = window.setTimeout("checkPos();", 500); 
} 
function checkPos() { 
    alert(_lastPosX); 
} 
Cuestiones relacionadas