Question JavaScript click écouteur d'événement en classe


J'essaie actuellement d'écrire du JavaScript pour obtenir l'attribut de la classe sur laquelle on a cliqué. Je sais que pour faire cela correctement, je devrais utiliser un écouteur d'événement. Mon code est le suivant:

var classname = document.getElementsByClassName("classname");

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    alert(attribute);
};

classname.addEventListener('click', myFunction(), false);

Je m'attendais à recevoir un message d'alerte chaque fois que je cliquais sur l'une des classes pour me dire l'attribut mais malheureusement cela ne fonctionne pas. Quelqu'un peut-il aider s'il vous plaît?

(Remarque - Je peux facilement le faire en jQuery mais je voudrais NE PAS aime l'utiliser)


115
2017-10-29 10:12


origine


Réponses:


Cela devrait fonctionner. getElementsByClassName renvoie un tableau Objet de type tableau (voir edit) des éléments correspondant aux critères.

var classname = document.getElementsByClassName("classname");

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    alert(attribute);
};

for (var i = 0; i < classname.length; i++) {
    classname[i].addEventListener('click', myFunction, false);
}

jQuery fait la partie en boucle pour vous, que vous devez faire en langage JavaScript.

Si tu as Support ES6 vous pouvez remplacer votre dernière ligne par:

    Array.from(classname).forEach(function(element) {
      element.addEventListener('click', myFunction);
    });

Remarque: les anciens navigateurs (tels que IE6, IE7, IE8) ne prennent pas en charge getElementsByClassName et ainsi ils reviennent undefined.


EDIT: correction

getElementsByClassName ne retourne pas un tableau, mais un HTMLCollection dans la plupart, ou un NodeList est un navigateur (Mozilla ref). Ces deux types sont Array-Like, ce qui signifie qu'ils ont une propriété length et que les objets sont accessibles via leur index, mais ne sont pas strictement un tableau ou hérités d'un tableau. (ce qui signifie que d'autres méthodes pouvant être effectuées sur un tableau ne peuvent pas être effectuées sur ces types)

Merci à l'utilisateur @Nemo pour le signaler et pour que je comprenne.


203
2017-10-29 10:31



* Ceci a été modifié pour permettre aux enfants de la classe cible de déclencher les événements. Voir en bas de la réponse pour plus de détails. *

Une autre réponse pour ajouter un écouteur d'événement à une classe où des éléments sont fréquemment ajoutés et supprimés. Ceci est inspiré par les jQuery on fonction où vous pouvez passer un sélecteur pour un élément enfant sur lequel l’événement écoute.

var baseSelector = '#base'; // selector for the container for the variable content
var base = document.querySelector(baseSelector);
var selector = '.card'; // any css selector for children

base.addEventListener('click', function(event) {
  // find the closest parent of the event target that
  // matches the selector
  // base selector needed to make sure we don't go outside the base element
  var closest = event.target.closest(baseSelector + ' ' + selector);
  if (closest) {
    // handle class event
  }
});

Violon: https://jsfiddle.net/u6oje7af/91/

Cela permettra d'écouter les clics sur les enfants du base element et si la cible d'un clic a un parent correspondant au sélecteur, l'événement de classe sera traité. Vous pouvez ajouter et supprimer des éléments comme vous le souhaitez sans avoir à ajouter d'autres écouteurs de clics aux différents éléments. Cela les interceptera même pour les éléments ajoutés après l'ajout de cet écouteur, tout comme la fonctionnalité jQuery (que j'imagine être un peu similaire sous le capot).

Cela dépend des événements se propageant, donc si vous stopPropagation sur l'événement ailleurs, cela peut ne pas fonctionner. Également closest la fonction a des problèmes de compatibilité avec IE apparemment (qu'est-ce qui ne fonctionne pas?).

Cela pourrait être transformé en une fonction si vous devez effectuer ce type d’action à plusieurs reprises, comme

function addChildEventListener(baseSelector, eventName, selector, handler) {
  var base = document.querySelector(baseSelector);
  base.addEventListener(eventName, function(event) {
    var closest = event.target.closest(baseSelector + ' ' + selector);
    if (closest) {
      // passes the event to the handler and sets `this`
      // in the handler as the closest parent matching the
      // selector from the target element of the event
      handler.call(closest, event);
    }
  });
}

=========================================
EDIT: Ce poste utilisait à l'origine le matches fonction pour les éléments DOM sur la cible de l'événement, mais cela restreint les cibles des événements à la classe directe uniquement. Il a été mis à jour pour utiliser le closest fonction à la place, permettant aux événements sur les enfants de la classe souhaitée de déclencher les événements aussi. L'original matchesle code peut être trouvé sur le violon original: https://jsfiddle.net/u6oje7af/23/


2
2018-06-17 23:34



Rappelez-vous toujours lors de l'utilisation de getElementsByClassName, vous devez utiliser une boucle pour accéder aux variables. Exemple:

var classname = document.getElementsByClassName("classname");
for(i=0;i<classname.length;i++){
classname[i].addEventListener('click', myFunction, false);
}

0
2018-06-25 12:56