2010-11-30 9 views
9

Quel est le meilleur moyen d'extraire l'objet événement lors de l'utilisation de setTimeout? J'utilise jQuery pour gérer la normalisation du modèle d'événement dans tous les navigateurs, mais je ne suis pas sûr de savoir comment placer l'objet 'e' dans la fonction checkPos.Javascript setTimeout appel de fonction avec argument d'événement?

Mon code actuel:

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); 
} 

Actuellement ce code fonctionne une fois parce que la fonction est appelée en cas mousedown, mais jamais à jour l'objet e que l'utilisateur déplace la souris. La console d'erreur FF javascript déclare également qu'il s'agit d'un appel inutile à setTimeout (guillemets manquants autour de l'argument?), Mais que suite à ce conseil, il échoue complètement.

Comment puis-je extraire l'argument 'e' d'un appel setTimeout?

Edit: Ajout dans le code qui rediffusions les checkPos fonctionnent toutes les 500ms

+1

Avec votre code, vous êtes invoquer en fait 'checkPos' lorsque vous appelez' setTimeout' (en raison de l'opérateur d'appel de fonction '()') et en faisant passer sa valeur de retour à ' setTimeout'; cette valeur n'est probablement pas une référence à une fonction, donc 'setTimeout' échoue. –

Répondre

7

Premièrement, pourquoi utilisez-vous deux délais d'attente? Il me semble que setInterval() serait mieux

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

pourrait vous Deuxièmement s'il vous plaît préciser ceci: « ... mais jamais à jour l'objet e que l'utilisateur déplace la souris. » Pourquoi l'objet événement serait-il mis à jour lorsque l'utilisateur déplace la souris? Vous avez seulement affecté un gestionnaire mouseDown. Si vous vouliez faire quelque chose à chaque déplacement de la souris, vous devriez utiliser un événement mouseMove, auquel cas le timeout/intervalle serait inutile de toute façon. Comme toujours en JavaScript, vous devriez d'abord chercher une solution pilotée par les événements et utiliser uniquement des gestionnaires temporisés quand vous en avez absolument besoin.

* Modifier - aborder les questions soulevées dans les commentaires op *

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

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

Essayez:

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

EDIT grâce aux commentaires OP ..

Pour avoir accès à un événement mis à jour chaque fois que checkPos est déclenché:

var myNamespace = {}; 

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

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

timerID = setInterval(checkPos, 500); 
+0

Désolé de reculer sur cette réponse, mais quand j'ai refait ce code en mettant checkPos (e); Il n'a pas réussi à intégrer l'événement e mis à jour après chaque expiration. –

+0

Cela ne fonctionnera pas avec votre code modifié. Cette méthode forme une «fermeture» sur «e». Pour accéder à un événement mis à jour, vous devez stocker l'événement dans un endroit accessible à la fonction 'checkPos' (externe) et mettre à jour cet événement stocké dans la fonction' MouseDownEvent'. – sje397

+0

Il n'y a aucun moyen d'appeler l'objet d'événement dans javascript ou jQuery de sorte que je puisse tirer dans la position actuelle de la souris en fonction du délai d'expiration? –

1

Vous pourriez utiliser une fonction curry, il y en a une pour jQuery here.

En général, vous auriez ceci:

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

var bar = curry(foo, 1); 

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

pour que vous puissiez faire:

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

Depuis cari retourne une fonction avec son premier argument lié à e, vous pouvez passer directement dans setTimeout .

1

Pour autant que je pouvais voir, IE ne permettra pas de passer le « événement » objet autour comme vous avez besoin. La seule solution que je peux envisager est de stocker à l'avance la valeur dont vous avez besoin en tant que variable globale, puis de vérifier cette variable dans la fonction retardée.

Par exemple: http://jsfiddle.net/YvYtn/1/

Cela montrera la dernière position X, vous pouvez stocker tout ce que vous avez besoin de l'objet événement.

Le code 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); 
}