2010-08-24 3 views
2

J'avons ajouté mes événements ainsi:retrait de l'événement dans Mootools et la syntaxe d'addition d'événements

element.addEvent('click', function() { 
    alert('foobar'); 
}); 

Cependant, lors d'une tentative de supprimer ledit événement, ce code syntaxiquement identique (avec « ajouter » commuté à " supprimer ") ne fonctionne pas. Je suppose que c'est parce que les deux fonctions définies ne sont pas référencées de la même manière, donc l'événement n'est pas techniquement supprimé. D'accord, donc je redéfinissent les plus d'événements et l'enlèvement:

element.addEvent('click', alert('foobar')); 
element.removeEvent('click', alert('foobar')); 

Ce qui fonctionne très bien, sauf que maintenant quand la page se charge, l'événement clique est avant même qu'il clique dessus!

La fonction est supprimée, mais, ce qui est génial ......

+0

Voici un jsfiddle: http://jsfiddle.net/wLuY3/ –

Répondre

4

mise à jour: lorsque vous faites .addEvent('type', function(){ }) et .removeEvent('type', function(){ }), même si les fonctions peuvent avoir les mêmes « signatures », ils sont deux fonctions anonymes separte, attribuées sur la mouche. la fonction 1 est! == à la fonction 2 - donc il n'y a pas de correspondance quand MooTools essaie de l'enlever.

pour pouvoir supprimer un gestionnaire exact, o:

{...} el.addEvent (clic, gestionnaire) gestionnaire de fonctions

(); // .. plus tard el.removeEvent ('click', handler);

En interne, les événements sont en réalité une carte des clés des fonctions dans le stockage des éléments. jetez un oeil à ce violon que j'ai fait il y a un moment pour une autre question SO - http://www.jsfiddle.net/mVJDr/

il vérifiera pour voir combien d'événements sont empilés pour un type d'événement particulier sur un élément donné (ou tous les événements).

De même, removeEvent recherche un résultat dans le stockage des événements - jetez un oeil sur http://jsfiddle.net/dimitar/wLuY3/1/. par conséquent, l'utilisation de fonctions nommées comme suggéré par Nikolaus vous permet de les supprimer facilement car elle fournit une correspondance. Vous pouvez également supprimer des événements via element.removeEvents("click") pour tous les événements click. Votre page affiche maintenant des alertes parce que vous transmettez l'alerte en tant que fonction et que vous l'exécutez avec les paramètres 'foobar'. METHOD suivi de () en javascript signifie exécuter le METHOD le précedant immédiatement, pas plus tard. Lorsque vous liez des fonctions à des événements, vous transmettez uniquement la référence (le nom de la méthode).

pour éviter d'utiliser une fonction anonyme et de passer argument s que vous pouvez faire quelque chose comme:

document.id('foobar').addEvent('click', alert.bind(this, 'foo')); 

comme le lier rappe pour vous, mais la suppression ce sera encore plus compliqué.

que pour la délégation de l'événement, il est:

parentEl.addEvents({ 
    "click:relay(a.linkout)": function(e, el) { 

    }, 
    "mouseover:relay(li.menu)": function(e, el) { 

    } 
}); 

plus sur ce ici http://mootools.net/docs/more/Element/Element.Delegation#Element:removeEvent

garder à l'esprit ce n'est pas grand/très stable. fonctionne bien pour les choses de clic, mouseenter ne doit pas être utilisé délégué, juste mouseover - ce qui signifie que IE peut déclencher le mouseout quand il ne devrait pas. la façon dont je comprends, il vient amélioré Mootools 2.0

modifier mise à jour pour montrer un exemple de méthode lié et non lié dans un modèle de classe dans Mootools

http://www.jsfiddle.net/wmhgw/

var foo = new Class({ 
    message: "hi", 
    toElement: function() { 
     return this.element = new Element("a", { 
      href: "http://www.google.com", 
      text: "google", 
      events: { 
       "click": this.bar.bind(this), // bind it 
       "mouseenter": this.bar // unbound -> this.element becomes this 
      } 
     }); 

    }, 
    bar: function(event) { 
     event.stop(); 
     // hi when bound to class instance (this.message will exist) 
     // 'undefined' otherwise. 
     console.log(this.message || "undefined"); 
    } 
}); 

document.id(new foo()).inject(document.body); 

le mouseenter ici sera non liée où this se référera à la portée par défaut (à savoir l'élément qui a déclenché l'événement - l'a href). quand il est lié, vous pouvez obtenir l'élément via event.target place - l'objet d'événement est toujours transmis à la fonction en tant que paramètre.

BTW, c'est une utilisation un peu moins familier de rapport de classe et de l'élément, mais il sert mes objectifs ici pour illustrer la liaison dans le cadre des classes.

+0

Merci pour la clarification sur les fonctions de js. Je ne savais pas que l'ajout de a() provoquait l'exécution de la fonction. Très intéressant. est-il un avantage à des fonctions de liaison dans votre exemple ci-dessus? –

+0

c'est le cas. c'est pourquoi vous obtenez des fermetures anonymes comme ce que le travail: '(function() {...})();' 'la()' est ce qui exécute la fonction après la création, en vous donnant bloquer la portée en javascript. quant au bind, il est utile de changer ce à quoi 'this' se référera dans la fonction d'exécution. pour Mootools en particulier lorsque vous utilisez souvent des classes/POO, vous avez tendance à affecter les méthodes de classe aux événements de souris où vous essayez aussi de garder la portée de la classe, soit dans la fonction de rappel 'this' sera l'instance de classe et non l'élément qui a été cliqué sur comme le serait –

1

Affect la fonction à une variable et utiliser la même référence pour ajouter et supprimer l'événement. si vous utilisez une fonction anonyme, vous obtiendrez à différentes références

var test = function(){ alert('test: ' + this.id); } 
$('element').addEvent('click', test); 

... 
$('element').removeEvent('click', test); 
0

addEvent: fixer un écouteur d'événement à un élément DOM.

Exemple -

$('myElement').addEvent('click', function(){ 
    alert('clicked!'); 
}); 

removeEvent: Fonctionne comme Element.addEvent, mais au lieu de l'auditeur supprime d'événement spécifié.

Exemple -

var destroy = function(){ alert('Boom: ' + this.id); } // this refers to the Element. 
$('myElement').addEvent('click', destroy); 

//later... 
$('myElement').removeEvent('click', destroy); 

Cela signifie que lorsque vous ajoutez un événement avec un eventhandler pas une fonction anonyme si vous que supprimer l'événement qu'il sera supprimé.