web-dev-qa-db-fra.com

Remplacer tous les événements JavaScript liés à un élément par un seul nouvel événement

En supposant qu'il existe un grand nombre d'éléments sur tout le site auxquels un nombre et un type d'événements inconnus sont liés.

Si je dois remplacer tous ces événements avec un seul événement lié et que seul cet événement se déclenchera, quelles sont les recommandations?

Je lierais l'événement à un gestionnaire d'événements Click, et j'utilise jQuery.

Merci d'avance.

24
jerome

Vous recherchez jQuery#unbind .

Pour supprimer tous les gestionnaires d'événements sur un élément ou un ensemble d'éléments, faites simplement:

$('.some-selector').unbind();

Pour dissocier uniquement les gestionnaires de clics, utilisez unbind('click'):

$('.some-selector').unbind('click');

Pour dissocier tous les gestionnaires de clics et lier immédiatement votre propre gestionnaire après cela, vous pouvez faire quelque chose comme ceci:

$('.some-selector').unbind('click').click(function(event) {
  // Your code goes here
});

Notez que cela ne fonctionnera que pour les événements liés à l'aide de jQuery (en utilisant .bind Ou toute méthode jQuery qui utilise .bind En interne). Si vous souhaitez supprimer tous les événements onclick possibles d'un ensemble d'éléments donné, vous pouvez utiliser:

$('.some-selector')
  .unbind('click') // takes care of jQuery-bound click events
  .attr('onclick', '') // clears `onclick` attributes in the HTML
  .each(function() { // reset `onclick` event handlers
    this.onclick = null;
  });
50
Mathias Bynens

Je voudrais fournir une pensée sans supprimer tous les événements tous ensemble (il suffit de les remplacer).

Si votre nouvel événement lié unique (nous l'appelons "clic" ici) est spécifique à l'élément auquel il se lie, alors je crois que vous pouvez ignorer tout autre événement simplement par la fonction stopPropagation (). Comme ça

$("specific-selector").on("click", ".specific-class", function (e) {
  e.stopPropagation()
  // e.stopImmediatePropagation()
  /* your code continues ... */
});

Cela arrêtera les bulles d'événements, de sorte que vos autres événements ne se déclencheront pas. utilisez stopImmediatePropagation () pour empêcher d'autres événements attachés aux mêmes éléments que le "clic".

Par exemple, si l'événement "mouseleave" est également lié à l'élément $ ("specific-selector .specific-class"), il ne se déclenchera pas non plus.

Enfin, tous les autres événements ne se déclencheront pas sur cet élément mais sur votre nouvel élément "clic".

La question non résolue est la suivante: et si d'autres événements utilisent également stopPropagation ()? ... Ensuite, je pense que celui avec les meilleures spécifications gagne, alors essayez d'éviter les événements complexes, trop d'événements est une suggestion finale.

Vous pouvez voir "Événements directs et délégués" sur site jQuery pour plus d'informations.

7
francischan

Essayez d'utiliser live au lieu de bind. Ensuite, vous pouvez facilement supprimer la liaison en direct avec die du sélecteur qui est une opération rapide et en définir une autre en direct tout aussi rapide.

   $('selection here').live('..', .....);  // multiple invocations
   $('selection here').die();
   $('selection here').live('click',.....);

DOM n'est pas du tout touché. La condition d'événement est évaluée lors de l'occurrence de l'événement.

Mais généralement, si vous souhaitez simplement échanger les fonctions du gestionnaire, pourquoi ne pas le faire de cette façon:

var ahandler = function(evt) { /* first implementation */ }
$('.selector').bind('click', function(evt) { ahandler(evt); });

//and then if you want to change handlers
ahandler = function(evt) { /* new implementation */ };

Cela ne donne absolument aucun coût pour les changements, la reliure, etc.

1
gertas

On dirait que c'est assez simple en fait:

$('#foo').unbind('click');
$('#foo').bind('click', myNewFunction);

Merci pour vos réponses.

1
jerome