В JavaScript обработчик события click по классу

в настоящее время я пытаюсь написать JavaScript, чтобы получить атрибут класса, который был нажат. Я знаю, что для этого нужно использовать прослушиватель событий. Мой код выглядит следующим образом:

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

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

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

Я ожидал получить окно предупреждения каждый раз, когда я нажал на один из классов, чтобы сказать мне атрибут, но, к сожалению, это не работает. Кто-нибудь может помочь?

(Примечание - Я могу легко сделать это в jQuery но я бы не как использовать)

3 ответов


это должно работать. getElementsByClassName возвращает массив массив-подобный объект (см. редактирование) элементов, соответствующих критериям.

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 делает часть цикла для вас, что вам нужно сделать в обычном JavaScript.

если у вас поддержка ES6 в вы можете заменить последнюю строку с:

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

Примечание: старые браузеры (например, IE6, IE7, IE8) не поддерживают getElementsByClassName и поэтому они возвращаются undefined.


EDIT: Correction

getElementsByClassName не возвращает массив, но HTMLCollection в большинстве, или NodeList-это некоторые браузеры (Mozilla ref). Оба эти типы массивов, (что означает, что они имеют свойство length, и объекты могут быть доступны через их индекс), но не строго массива или наследуется из массива. (это означает, что другие методы, которые могут быть выполнены на массиве, не могут быть выполнены на этих типы)

Спасибо пользователю @Немо за то, что указал на это и заставил меня полностью понять.


* это было отредактировано, чтобы разрешить детям целевого класса запускать события. Подробнее см. В нижней части ответа. *

альтернативный ответ для добавления прослушивателя событий в класс, где элементы часто добавляются и удаляются. Это вдохновлено jQuery on функция, в которой вы можете передать селектор для дочернего элемента, который прослушивает событие.

var base = document.querySelector('#base'); // the container for the variable content
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
  var closest = event.target.closest(selector);
  if (closest && base.contains(closest)) {
    // handle class event
  }
});

Скрипка: https://jsfiddle.net/u6oje7af/94/

это будет слушать клики на детей base элемент и если цель щелчка имеет родителя, соответствующего селектору, событие класса будет обработано. Вы можете добавлять и удалять элементы, как вам нравится, без необходимости добавлять дополнительные прослушиватели кликов к отдельным элементам. Это поймает их всех даже для элементов, добавленных после добавления этого прослушивателя, так же, как функциональность jQuery (которая, я полагаю, несколько похожа под капотом.)

это зависит от распространяющихся событий, поэтому, если вы stopPropagation на мероприятии где-то еще, это может не сработать. Кроме того,closest функция имеет некоторые проблемы совместимости с IE, видимо (что не так?).

это может быть сделано в функцию, если вам нужно сделать этот тип действий прослушивания неоднократно, как

function addChildEventListener(base, eventName, selector, handler) {
  base.addEventListener(eventName, function(event) {
    var closest = event.target.closest(selector);
    if (closest && base.contains(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: этот пост первоначально использовал matches функция для DOM элементы цели события, но это ограничивало цели событий только прямым классом. Он был обновлен, чтобы использовать closest вместо этого функция, позволяющая событиям на дочерних элементах желаемого класса также запускать события. Оригинал matches код можно найти на оригинальной скрипке: https://jsfiddle.net/u6oje7af/23/


всегда помните, что при использовании getElementsByClassName вы должны использовать цикл для доступа к переменным. Пример:

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