最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Why Javascript event handler is called twice? - Stack Overflow

programmeradmin13浏览0评论

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>

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.

Share Improve this question edited Mar 29, 2021 at 15:03 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Mar 29, 2021 at 8:28 WilliamWilliam 1,0062 gold badges16 silver badges37 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

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 divs, 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>

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 remend 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>

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;
    }
发布评论

评论列表(0)

  1. 暂无评论