我目前正在尝试编写一些JavaScript来获取已单击的类的属性。我知道要以正确的方式执行此操作,我应该使用事件侦听器。 我的代码如下:
var classname = document.getElementsByClassName("classname");
var myFunction = function() {
var attribute = this.getAttribute("data-myattribute");
alert(attribute);
};
classname.addEventListener('click', myFunction(), false);
每次点击其中一个类告诉我属性时,我都希望得到一个警告框,但遗憾的是这不起作用。有人可以帮忙吗?
(注意 - 我可以很容易地在jQuery
中执行此操作,但我 NOT 喜欢使用它)
答案 0 :(得分:265)
这应该有效。 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
。
编辑:更正
getElementsByClassName
不返回数组,但大多数情况下都是HTMLCollection,或NodeList是某些浏览器(Mozilla ref)。这两种类型都是Array-Like,(意味着它们具有length属性,并且可以通过索引访问对象),但严格来说不是Array或从Array继承。 (意味着无法对这些类型执行可在阵列上执行的其他方法)
感谢用户@ Nemo指出这一点并让我深入了解。
答案 1 :(得分:9)
使用现代JavaScript,可以这样完成:
const divs = document.querySelectorAll('.a');
divs.forEach(el => el.addEventListener('click', event => {
console.log(event.target.classList[1]);
}));
<!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 a-1">1</div>
<div class="b">2</div>
<div class="a a-2">11</div>
</body>
</html>
event.target
检索有关特定元素的更多信息答案 2 :(得分:8)
*对此进行了编辑,以允许目标类的子级触发事件。有关详细信息,请参阅答案底部。 * 强>
将事件侦听器添加到经常添加和删除项的类的替代答案。这是受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 :(得分:1)
您可以使用以下代码:
document.body.addEventListener('click', function (evt) {
if (evt.target.className === 'databox') {
alert(this)
}
}, false);
答案 4 :(得分:1)
现在可以使用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")
}
})
}
答案 5 :(得分:0)
还请考虑,如果您单击按钮,则事件监听器的 target 不一定是按钮本身,而是您单击的按钮内的任何内容。您可以使用 currentTarget 属性引用为侦听器分配的元素。这是使用单个语句在现代ES中提供的漂亮解决方案:
document.querySelectorAll(".myClassName").forEach(i => i.addEventListener(
"click",
e => {
alert(e.currentTarget.dataset.myDataContent);
}));