11
votes

JavaScript Settimeout Fonction Appel avec argument d'événement?

Quelle est la meilleure façon de tirer dans l'objet de l'é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 sais pas comment obtenir l'objet "E" dans la fonction CheckPos.

Mon code actuel: P>

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


1 commentaires

Avec votre code, vous appelez réellement checkpos lorsque vous appelez SetTimeout (en raison de l'opérateur d'invocation de la fonction () ) et de transmettre sa valeur de retour à Settimeout ; Cette valeur n'est probablement pas une référence à une fonction, donc Settimeout échoue.


4 Réponses :


10
votes

Essayez:

var myNamespace = {};

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

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

timerID = setInterval(checkPos, 500);


7 commentaires

Désolé de revenir sur cette réponse, mais quand j'ai réaffirmé ce code mettant la checkpos (e); Dans, il n'a pas réussi à apporter l'événement E mis à jour après chaque délai d'attente.


Cela ne fonctionnera pas avec votre code édité. Cette méthode constitue une "fermeture" sur E . Pour accéder à un événement mis à jour, vous devez stocker l'événement quelque part accessible à la fonction checkpos (externe à celui-ci) et à la mise à jour de cet événement stocké dans la fonction MouseDownEvent .


Il n'y a aucun moyen d'appeler l'objet événement dans JavaScript ou JQuery de telle sorte que je puisse tirer dans la position actuelle de la souris en fonction du délai d'attente?


@C Bauer peut-être cela aiderait si vous avez expliqué pourquoi vous devez utiliser un délai d'attente. JavaScript a un événement de Mousemove pour interroguer la position de la souris. Je ne vois donc pas pourquoi vous voudriez utiliser un délai d'attente. Voir ma réponse pour plus.


@Ollie - Le snip contient une boucle et un autre code qui deviendrait un goulot d'étranglement s'il est attaché à dire, l'événement Mousemove, mais il doit s'intégrer régulièrement.


@C Bauer: Vous pouvez attacher dans l'événement de déplacement de la souris pour simplement mettre à jour mynamespace.mousepos ou somesuch, puis avez-vous appelé votre fonction sur une minuterie ... Mieux à utiliser setInterval aussi.


@C Bauer Dans ce cas, je créerais un objet wrapper contenant un compteur et mes manuels d'événement. Chaque fois que le gestionnaire d'événements est exécuté incrémentez le compteur et ne gérez que votre code coûteux, disons toutes les 100 itérations ou tout ce qui fonctionne pour vous. Ceci est plus efficace puis en utilisant un intervalle car il ne tire pas à moins que la souris soit déplacée. Je vais ajouter cet exemple à ma réponse.



1
votes

Vous pouvez utiliser une fonction de curry, il y en a un pour jQuery ici .

Généralement , vous auriez ceci: xxx

afin que vous puissiez faire: xxx

car le curry renvoie une fonction avec son premier argument lié à E, vous pouvez le transmettre directement à SetTimeOUT.


0 commentaires

8
votes

Tout d'abord, pourquoi utilisez-vous deux délais d'attente? Il me semble que comme seinterval () serait mieux xxx pré>

Deuxièmement, pourriez-vous clarifier cela: "... mais ne met jamais à jour l'objet E lorsque l'utilisateur déplace la souris." Pourquoi l'objet d'événement serait-il mis à jour lorsque l'utilisateur déplace la souris? Vous avez seulement attribué un gestionnaire de MouseDown. Si vous vouliez faire quelque chose sur chaque mouvement de la souris, vous devez utiliser un événement de Mousemove, auquel cas le délai d'attente / intervalle serait inutile de toute façon. P> xxx pré>

comme toujours en JavaScript devrait rechercher d'abord une solution entraînée par événement et utiliser uniquement des gestionnaires chronométrés lorsque vous devez absolument. p>

* Modifier - Répondre Problèmes OP soulevés dans les commentaires * P>

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

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


0 commentaires

1
votes

Autant que je puisse le voir, c'est-à-dire que vous ne permettrez pas de passer l'objet "Événement" autour de vous comme si vous avez besoin.

La seule solution de contournement que je peux penser à la valeur de la valeur dont vous avez besoin à l'avance en tant que variable globale puis vérifiez cette variable dans la fonction retardée. p>

Par exemple: http://jsfiddle.net/yvytn / 1 / p>

Ceci affichera la dernière position X, vous pouvez stocker tout ce dont vous avez besoin de l'objet événement. P>

Code JS: P>

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


0 commentaires