JavaScript在类上点击事件监听器

我目前正在尝试编写一些JavaScript来获得已单击的类的属性。我知道,要正确地做到这一点,我应该使用事件侦听器。 我的代码如下:

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


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


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

我期待得到一个警告框,每次我点击一个类告诉我的属性,但不幸的是,这并不管用。有人能帮忙吗?

(__abc1 - __abc2)

593261 次浏览

这应该有用。getElementsByClassName返回一个类似数组的对象(见下文),包含符合条件的元素。

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


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


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

jQuery为您完成循环部分,这需要在纯JavaScript中完成。

如果你有ES6支持,你可以用:

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

注意:旧的浏览器(如IE6, IE7, IE8)不支持getElementsByClassName,所以他们返回undefined


getElementsByClassName的详细信息

getElementsByClassName不返回数组,但在大多数浏览器中返回HTMLCollection,或在某些浏览器中返回NodeList (Mozilla裁判)。这两种类型都是类似Array的(意味着它们有一个length属性,对象可以通过它们的索引访问),但不是严格意义上的Array或继承自Array(意味着可以在Array上执行的其他方法不能在这些类型上执行)。

感谢用户@尼莫指出这一点,并让我深入了解。

*这被编辑为允许目标类的子类触发事件。详情见答案底部。*

向经常添加和删除项的类添加事件侦听器的另一种解决方案。这是受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);
}
});
}
< p >=========================================< br > 编辑:这篇文章最初使用matches函数用于事件目标上的DOM元素,但这仅将事件的目标限制为direct类。它已被更新为使用closest函数代替,允许所需类的子类上的事件触发事件。原始的matches代码可以在原始的fiddle中找到: https://jsfiddle.net/u6oje7af/23/ < / p >

你可以使用下面的代码:

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

使用现代JavaScript可以这样做:

const divs = document.querySelectorAll('.a');


divs.forEach(el => el.addEventListener('click', event => {
console.log(event.target.getAttribute("data-el"));
}));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Example</title>
<style>
.a {
background-color:red;
height: 33px;
display: flex;
align-items: center;
margin-bottom: 10px;
cursor: pointer;
}
    

.b {
background-color:#00AA00;
height: 50px;
display: flex;
align-items: center;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="a" data-el="1">1</div>
<div class="b" data-el="no-click-handler">2</div>
<div class="a" data-el="3">11</div>
</body>
</html>

  1. 按类名获取所有元素
  2. 使用forEach循环遍历所有元素
  3. 在每个元素上附加一个事件监听器
  4. 使用event.target检索特定元素的更多信息

你可以使用querySelectorAll来选择所有的类,并循环遍历它们来分配eventListener。if条件检查它是否包含类名。

const arrClass = document.querySelectorAll(".className");
for (let i of arrClass) {
i.addEventListener("click", (e) => {
if (e.target.classList.contains("className")) {
console.log("Perfrom Action")
}
})
}

还要考虑如果单击按钮,事件侦听器的目标不一定是按钮本身,而是您所单击的按钮内部的任何内容。您可以使用currentTarget属性引用为其分配侦听器的元素。下面是现代ES中使用单一语句的一个漂亮的解决方案:

    document.querySelectorAll(".myClassName").forEach(i => i.addEventListener(
"click",
e => {
alert(e.currentTarget.dataset.myDataContent);
}));

以上所有的答案都是正确的,我只是想演示另一种简单的方法

document.querySelectorAll('.classname').forEach( button => {
button.onclick = function () {
// rest of code
}
});