[英]addEventListener for click event is overwritten
I'm pretty new to HTML/JS and am trying to learn all the oddities.我对 HTML/JS 很陌生,并且正在尝试学习所有奇怪的东西。 In trying to get this to work, I learned that only one
Element.onclick = function() {}
is allowed and if you try to add more the previous ones will be overwritten.在试图让它工作时,我了解到只允许一个
Element.onclick = function() {}
,如果你尝试添加更多,以前的将被覆盖。 But now I'm facing the same thing by using Element.addEventListener("click", function() {})
.但是现在我使用
Element.addEventListener("click", function() {})
面临同样的事情。 Here's my code:这是我的代码:
<html>
<body id="body">
</body>
</html>
<script>
window.onload = function() {
for (var buttonText of ["item1", "item2", "item3"]){
var button = document.createElement("button");
button.textContent = buttonText;
button.addEventListener("click", function(){
console.log(`${buttonText} was clicked!`);
});
document.getElementById("body").append(button);
}
}
</script>
No matter which button is clicked, the console always says item3 was clicked!
无论点击哪个按钮,控制台总是说
item3 was clicked!
. . Where am I going wrong?
我哪里错了?
It has to do with the scope of the variable.它与变量的 scope 有关。
addEventListener
will add an event and that time though the call back will fire but the loop have finished it's execution & buttonText
will be updated with latest value. addEventListener
将添加一个事件,此时虽然回调会触发,但循环已完成它的执行, buttonText
将使用最新值更新。 This is causing buttonText
to be always item3
.这导致
buttonText
始终item3
。 One option is to replace for (var buttonText of ["item1", "item2", "item3"]) {
with for (let buttonText of ["item1", "item2", "item3"]) {
一种选择是将
for (var buttonText of ["item1", "item2", "item3"]) {
替换for (let buttonText of ["item1", "item2", "item3"]) {
window.onload = function() { for (let buttonText of ["item1", "item2", "item3"]) { let button = document.createElement("button"); button.textContent = buttonText; button.addEventListener("click", function() { console.log(`${buttonText} was clicked;`); }). document.getElementById("body");append(button); } }
<div id='body'></div>
Another option is you can create a closure
and an IIFE
另一种选择是您可以创建一个
closure
和一个IIFE
window.onload = function() { for (var buttonText of ["item1", "item2", "item3"]) { // start of IIFE (function(txt) { var button = document.createElement("button"); button.textContent = txt; button.addEventListener("click", function() { console.log(`${txt} was clicked;`); }). document.getElementById("body");append(button); }(buttonText)) } }
<div id='body'></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.