使用纯JavaScript,是否有一种简单的方法将事件监听器附加到类?

时间:2017-12-06 14:22:50

标签: javascript

我正在寻找与

相当的JavaScript
$(".class-name").on(eventName, eventHandler);

首先我尝试了

document.querySelectorAll(".class-name").addEventListener(eventName, eventHandler);

但它不起作用。在JavaScript中有一种简单的方法吗?

------ ------更新

很多答案都提出了一个循环,但最初我正在寻找一个带有单个监听器的解决方案来节省内存(假设我在该类中有1000个项目)。 但是,有一个答案提醒我:jQuery版本是否也在内存中创建了1000个侦听器?

6 个答案:

答案 0 :(得分:4)

jQuery会将传递给on的事件处理程序分配给与选择器匹配的所有元素。香草JS不这样做。 document.querySelectorAll返回NodeList,因此您需要选择所需的特定节点并为其分配事件侦听器。如果要将事件侦听器分配给列表中的所有节点,则可以迭代NodeList,如下所示:

var nodes = document.querySelectorAll(".class-name");
for (var node in nodes) {
    node.addEventListener(event, handler);
}

答案 1 :(得分:0)

你可以循环document.getElementsByClassName('this-is-the-class-you-are-searching-for')喜欢

document.getElementsByClassName('selector-class').forEach(function (e) {
  e.addEventListener('click', function (event) {
    console.log('Oh dang, you just clicked!');
  });
});

正如Alex M.所指出的,某些浏览器(如InternetExplorer)不支持NodeList.forEach。因此,您可以使用不同的语法(for)或使用像babel这样的转换器来确保代码的广泛支持! polyfill from MDN也非常小。

答案 2 :(得分:0)

这是等效的(这也适用于未来的节点)

document.addEventListener("click", function(e) {
  var el = e.target;
  if (el.classList.contains("class-name")) {
    // handle event e for element el
  }
});

编辑:虽然在jQuery中也是如此,但这种方式实际上优于问题中的示例。此侦听器还将捕获添加侦听器时不存在的元素的单击。

答案 3 :(得分:0)

将所有元素存储在数组中并将事件绑定到所有元素。这里document.getElementsByClassName返回具有类class-name的元素数组。

var classes= document.getElementsByClassName("class-name");

 Array.from(classes).forEach(function(element) {
      element.addEventListener('click', function(){alert('clicked'+   this.innerHTML)});
    });
<div class="class-name">
First div  1
</div>

<div class="class-name">
Second div    2
</div>

<div class="class-name">
third div   3
</div>
.
.
.
<div class="class-name">
nth div     n
</div>

修改

getElementsByClassName不返回数组,但大多数情况下都是HTMLCollection,或NodeList是某些浏览器(Mozila ref)。这两种类型都是Array-Like,(意味着它们具有length属性,并且可以通过索引访问对象),但严格来说不是Array或从Array继承。 (意味着无法对这些类型执行可在阵列上执行的其他方法)

答案 4 :(得分:0)

问题是querySelectorAll返回一个nodeList,如果您只使用querySelector查找一个类,您的代码将起作用,但只能绑定到一个元素。

选项1:迭代NodeList + Bind

一种选择是迭代节点列表中的所有节点并将事件绑定到它们:

let eventName = 'click';
let elements  = document.querySelectorAll('.foo');
[...elements].forEach(el=>el.addEventListener(eventName, eventHandler));


function eventHandler (){
  console.log(`Clicked: "${this.textContent}"`);
}
<div class="foo">Click Me</div>
<div class="foo">Or this</div>

注意:上面使用ES6语法,如果你需要一个更符合的迭代方法,你可以尝试: [].forEach.call(elements, function(el) { ... });

选项2:将一次绑定到共同祖先

另一个选择是找到最近的共同祖先并将一个事件绑定到那个,然后看看你关心的类是否是目标并调用该函数,如果是的话。

答案 5 :(得分:-1)

是的,绝对!

编辑:原来你要将它添加到该类的每个元素。在这种情况下,你应该尝试使用

let elements = document.getElementsByClassName("myClass")

之后,您可以使用for循环遍历它们并附加事件侦听器。