JavaScript-прослушиватель событий в классе

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

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

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

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

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

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

Ответ 1

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

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.


РЕДАКТИРОВАТЬ: Коррекция

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

Благодаря пользователю @Nemo за то, что вы указали это, и заставив меня полностью понять.

Ответ 2

* Это было отредактировано, чтобы позволить детям целевого класса вызывать события. Смотрите в нижней части ответа для деталей. *

Альтернативный ответ для добавления прослушивателя событий в класс, где элементы часто добавляются и удаляются. Это основано на функции 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);
    }
  });
}

=========================================
ОБНОВЛЕНИЕ: Эта публикация первоначально использовала функцию matches для элементов DOM на цели события, но это ограничивало цели событий только прямым классом. Он был обновлен, чтобы использовать вместо него функцию closest, позволяющую событиям дочерних классов желаемого класса также инициировать события. Оригинальный код matches можно найти на оригинальной скрипке:https://jsfiddle.net/u6oje7af/23/

Ответ 3

Вы можете использовать код ниже:

document.body.addEventListener('click', function (evt) {
    if (evt.target.className === 'databox') {
        alert(this)
    }
}, false);