我不明白下面的行为。
我希望下面的脚本能够执行以下操作:
i
的提醒。所以我希望点击“按钮1”会提示“我是按钮1”。
相反,所有3个按钮都提醒“我是按钮3”。看起来i
计数器的值不会被保留。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
</head>
<body>
<p class="button">Button 0</p>
<p class="button">Button 1</p>
<p class="button">Button 2</p>
<script>
var buttons = document.getElementsByClassName('button');
for (var i=0 ; i < buttons.length ; i++){
buttons[i].onclick = function(){
alert("I am button " + i);
};
}
</script>
</body>
</html>
为什么会这样?我怎样才能达到预期的行为?
答案 0 :(得分:2)
试试这个。它被称为Closures。它捕获变量i
,因为在循环后未删除i
,它会使用当前值i
调用事件处理程序。所以你需要一个局部变量,你可以通过执行函数来获得它。所以我创建了一个函数,将一个变量i
传递给他,在函数范围内,我有一个函数本地的变量param
,这是每次迭代的新变量。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
</head>
<body>
<p class="button">Button 0</p>
<p class="button">Button 1</p>
<p class="button">Button 2</p>
<script>
var buttons = document.getElementsByClassName('button');
for (var i=0 ; i < buttons.length ; i++){
buttons[i].onclick = (function(param){
return function(){
alert("I am button " + param);
};
})(i);
}
</script>
</body>
</html>
&#13;
或者您可以使用ES6 feature let
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
</head>
<body>
<p class="button">Button 0</p>
<p class="button">Button 1</p>
<p class="button">Button 2</p>
<script>
var buttons = document.getElementsByClassName('button');
for (let i = 0 ; i < buttons.length ; i++){
buttons[i].onclick = function(){
alert("I am button " + i);
}
}
</script>
</body>
</html>
&#13;
答案 1 :(得分:0)
回调button.onclick
是一个闭包,它在堆栈中有对i变量的引用,它等于循环中的最后一个值