当我向类的元素添加事件处理程序时,如下所示:
<html>
<head>
<title>test</title>
</head>
<body>
<div class="class1" id="div1">div1</div>
<script>
var divs = document.getElementsByClassName("class1");
var onclick = function() {
alert("clicked");
}
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener("click", onclick);
}
</script>
</body>
</html>
如果我点击 div 元素,警报窗口会弹出两次。但是如果我使用下面的代码,警告窗口只会弹出一次。
<html>
<head>
<title>test</title>
</head>
<body>
<div class="class1" id="div1">div1</div>
<script>
var divs = document.getElementsByClassName("class1");
var onclick = function() {
alert("clicked");
}
divs.addEventListener("click", onclick);
</script>
</body>
</html>
以下代码也两次弹出警告窗口:
<html>
<head>
<title>test</title>
</head>
<body>
<div class="class1" id="div1">div1</div>
<script>
var div = document.getElementById("div1");
var onclick = function() {
alert("clicked");
}
div.addEventListener("click", onclick);
</script>
</body>
</html>
我想知道为什么事件处理程序被调用两次,无论我使用 addEventListener("click",onclick, true);
还是 addEventListener("click",onclick,false);
我使用火狐浏览器。
答案 0 :(得分:3)
发生这种情况是因为您的 onclick
变量是一个全局变量,这意味着您在将函数分配给 onclick
时实际上是在执行此操作:
window.onclick = function () {
alert('click');
};
因此,您将事件侦听器添加到 div
、和 window
,当您单击 div
时,它会在div
,还有一次在 window
上。
为避免这种情况,请使用 iife 将您的变量从全局范围中屏蔽:
<html>
<head>
<title>test</title>
</head>
<body>
<div class="class1" id="div1">div1</div>
<script>
(function () {
var divs = document.getElementsByClassName("class1");
var onclick = function() {
alert("clicked");
}
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener("click", onclick);
}
})();
</script>
</body>
</html>
答案 1 :(得分:1)
为什么要循环。除了名称(您覆盖本机 onclick)问题之外,为什么不只添加一次?您只有一个具有唯一 ID 的 div。
使用匿名函数可以更安全地避免意外使用本机函数名
const div = document.getElementById("div1");
div.addEventListener("click", () => {
alert("clicked");
});
<div class="class1" id="div1">div1</div>
如果您有多个元素使用同一个事件处理程序,请委托
document.getElementById("container").addEventListener("click", (e) => {
const div = e.target.closest("div");
if (div && div.classList.contains("class1")) {
alert(div.id + " clicked");
}
});
<div id="container">
<div class="class1" id="div1">div1</div>
<div class="class1" id="div2">div2</div>
</div>