Reputation: 976
When I add an event handler to element of a class as follows:
<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>
The alert window is popped up twice if I click on the div element. But if I use the following code, the alert window is only popped up once.
<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>
The following code also pops up the alert window twice:
<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>
I wonder why the event handler is called twice, regardless I use addEventListener("click",onclick, true);
or addEventListener("click",onclick,false);
I use Firefox browser.
Upvotes: 1
Views: 3897
Reputation: 11
The only solution that worked for me was to force that the addEventListener
to be called once.
Like:
if (!window.onClickListenerAdded) {
const onClickListener = (event) => {
alert("clicked");
};
window.removeEventListener('click', onClickListener);
window.addEventListener('click', onClickListener);
window.onClickListenerAdded = true;
}
Upvotes: 0
Reputation: 177786
Why loop at all. Apart from the name (you overwrite the native onclick) issue, why not just add once? You have only one div with a unique ID.
Using an anonymous function makes it even safer not to accidentally use a native function name
const div = document.getElementById("div1");
div.addEventListener("click", () => {
alert("clicked");
});
<div class="class1" id="div1">div1</div>
NOTE: Be careful using anonymous functions in a loop though. I never do so we are safe here
If you have more than one element to use the same event handler, I always recommend to delegate
document.getElementById("container").addEventListener("click", (e) => {
const div = e.target.closest("div");
if (div && div.matches(".class1")) {
alert(div.id + " clicked");
}
});
<div id="container">
<div class="class1" id="div1">div1</div>
<div class="class1" id="div2">div2</div>
</div>
Upvotes: 2
Reputation: 101662
This is happening because your onclick
variable is a global variable, and that means you are essentially doing this when you assign the function to onclick
:
window.onclick = function () {
alert('click');
};
So you are adding the event listener to your div
s, and window
, and when you click the div
, it is firing once on the div
, and once on the window
.
To avoid this, use an iife to shield your variables from the global scope:
<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>
Upvotes: 4