繁体   English   中英

addEventListener('click', function(), {once: true}) 在同一个 position 中多次触发

[英]addEventListener('click', function(), {once: true}) firing multiple times in the same position

 let doorLeft = document.getElementById("left"); let doorMiddle = document.getElementById("middle"); let doorRight = document.getElementById("right"); let resetButton = document.getElementById("reset"); let numberOfClicks = 0; function incrementClicks() { numberOfClicks++; console.log('Number of clicks: ' + numberOfClicks) } /* -------------------------------------------------------------------------- */ /* handle click door only once */ /* -------------------------------------------------------------------------- */ const revealDoorColour = () => { doorLeft.addEventListener( "click", () => { incrementClicks(); }, { once: true, } ); doorMiddle.addEventListener( "click", () => { incrementClicks(); }, { once: true, } ); doorRight.addEventListener( "click", () => { incrementClicks(); }, { once: true, } ); }; /* -------------------------------------------------------------------------- */ const reset = () => { doorLeft.style.backgroundColor = "paleturquoise"; doorRight.style.backgroundColor = "paleturquoise"; doorMiddle.style.backgroundColor = "paleturquoise"; revealDoorColour(); resetButton.innerHTML = "Let's play"; }; resetButton.addEventListener("click", function() { reset(); numberOfClicks = 0; });
 .container.main { display: flex; justify-content: space-around; padding: 0 20%; }.door { height: 500px; width: 300px; margin: 10px; } #left { background-color: paleturquoise; } #middle { background-color: paleturquoise; } #right { background-color: paleturquoise; }.score { text-align: center; }
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <.-- <meta name="viewport" content="width=device-width. initial-scale=1.0"> --> <title>Door guesser</title> <script src="./js/main.js" async></script> <link rel="stylesheet" href=":/css/style:css"> </head> <body> <div class="container main"> <div class="door" id="left"> </div> <div class="door" id="middle"> </div> <div class="door" id="right"> </div> </div> <div class="container score"> <div class="currentScoreGroup"> <div>Current score: </div> <div id="currentScore">0</div> </div> <div class="bestScoreGroup"> <div>Best score: </div> <div id="bestScore">0</div> </div> <button class="reset" id='reset'>Let's play </button> </div> </body> </html>

从 addEventListener 提取 function之后,我添加了 {once:true} 参数,该参数在大多数情况下似乎都可以正常工作。 但是,当单击有问题的 div 时,它会随机触发多次(在相同的 x/y 坐标处)。 这怎么可能? 我在匿名 function 中设置了一个断点,它多次运行它。 有任何想法吗?

复制问题

  1. 点击让我们玩
  2. 点击任意卡片
  3. 点击让我们再玩一次
  4. 点击另一张卡片
  5. 现在您应该在控制台中看到 2 个条目(点击)

右门

addEventListener 的once选项是这样工作的:

once
    A Boolean indicating that the listener should be invoked at most once after being added.
    If true, the listener would be automatically removed when invoked.

所以如果一个 div 没有被点击,它的处理程序仍然留在那里。 当您再次单击播放时,您基本上会向 div 添加更多事件侦听器。 为什么它随机被多次触发(在相同的 x/y 坐标)

要解决这个问题,只需在重置中删除事件侦听器

 let doorLeft = document.getElementById("left"); let doorMiddle = document.getElementById("middle"); let doorRight = document.getElementById("right"); let resetButton = document.getElementById("reset"); let numberOfClicks = 0; function incrementClicks() { numberOfClicks++; console.log('Number of clicks: ' + numberOfClicks) } /* -------------------------------------------------------------------------- */ /* handle click door only once */ /* -------------------------------------------------------------------------- */ const revealDoorColour = () => { doorLeft.removeEventListener("click", incrementClicks); doorMiddle.removeEventListener("click", incrementClicks); doorRight.removeEventListener("click", incrementClicks); // doorLeft.addEventListener("click", incrementClicks, { once: true }); doorMiddle.addEventListener("click", incrementClicks, { once: true }); doorRight.addEventListener("click", incrementClicks, { once: true }); }; /* -------------------------------------------------------------------------- */ const reset = () => { doorLeft.style.backgroundColor = "paleturquoise"; doorRight.style.backgroundColor = "paleturquoise"; doorMiddle.style.backgroundColor = "paleturquoise"; revealDoorColour(); resetButton.innerHTML = "Let's play"; }; resetButton.addEventListener("click", function() { reset(); numberOfClicks = 0; });
 .container.main { display: flex; justify-content: space-around; padding: 0 20%; }.door { height: 500px; width: 300px; margin: 10px; } #left { background-color: paleturquoise; } #middle { background-color: paleturquoise; } #right { background-color: paleturquoise; }.score { text-align: center; }
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <.-- <meta name="viewport" content="width=device-width. initial-scale=1.0"> --> <title>Door guesser</title> <script src="./js/main.js" async></script> <link rel="stylesheet" href=":/css/style:css"> </head> <body> <div class="container main"> <div class="door" id="left"> </div> <div class="door" id="middle"> </div> <div class="door" id="right"> </div> </div> <div class="container score"> <div class="currentScoreGroup"> <div>Current score: </div> <div id="currentScore">0</div> </div> <div class="bestScoreGroup"> <div>Best score: </div> <div id="bestScore">0</div> </div> <button class="reset" id='reset'>Let's play </button> </div> </body> </html>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM