繁体   English   中英

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

[英]With pure JavaScript, is there an easy way to attach an event listener to a class?

我正在寻找相当于JavaScript的

$(".class-name").on(eventName, eventHandler);

我先试过

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

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

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

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

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

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

你可以循环遍历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这样的转换器来确保代码的广泛支持! 来自MDNpolyfill也非常小。

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

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

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

将所有元素存储在数组中并将事件绑定到所有元素。 这里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继承。 (意味着无法在这些类型上执行可在阵列上执行的其他方法)

问题是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:绑定一次到共同的祖先

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

是的,一点没错!

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

let elements = document.getElementsByClassName("myClass")

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM