我有以下代码,当我点击一个按钮时,我希望警报显示prizes数组中的字符串,该字符串对应于等于按钮编号的索引。我目前收到“Fresh Laundry!”。
<button id="btn-0">Button 1!</button>
<button id="btn-1">Button 2!</button>
<button id="btn-2">Button 3!</button>
<script type="text/javascript">
var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length - 1; btnNum++) {
document.getElementById('btn-' + btnNum).onclick = function() {
alert(prizes[btnNum]);
};
}
</script>
答案 0 :(得分:1)
您的代码存在与闭包有关的问题,在alert(prizes[btnNum])
中使用的btnNum在循环结束后的值为2。如果你只是在事件处理程序中使用每个元素的id来从数组中获取奖励会更好,如下所示:
<button id="btn-0">Button 1!</button>
<button id="btn-1">Button 2!</button>
<button id="btn-2">Button 3!</button>
<script type="text/javascript">
var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length; btnNum++) {
document.getElementById('btn-' + btnNum).onclick = function() {
var id = this.id;
alert(prizes[id.charAt(id.length-1)]);
};
}
</script>
&#13;
答案 1 :(得分:0)
这是因为调用闭包时,btnNum
已设置为32。
您可以这样做:
<script type="text/javascript">
var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length - 1; btnNum++) {
(function(_btnNum) {
document.getElementById('btn-' + _btnNum).onclick = function() {
alert(prizes[_btnNum]);
}
})(btnNum);
}
</script>
&#13;
答案 2 :(得分:0)
您可以尝试在按钮中设置一个值:
<button id="btn-0">Button 1!</button>
<button id="btn-1">Button 2!</button>
<button id="btn-2">Button 3!</button>
<script type="text/javascript">
var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length - 1; btnNum++) {
document.getElementById('btn-' + btnNum).value = btnNum;
document.getElementById('btn-' + btnNum).onclick = function() {
alert(prizes[this.value]);
};
}
</script>
自己找你最喜欢的方法
答案 3 :(得分:0)
为什么不
var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
function clickHandler (btnNum) {
alert(prizes[btnNum])
};
<button id="btn-0" onclick="clickHandler(0)">Button 1!</button>
<button id="btn-1" onclick="clickHandler(1)">Button 2!</button>
<button id="btn-2" onclick="clickHandler(2)">Button 3!</button>
当然HTML中的onclick处理程序有点可怕,但是在设计代码示例背后没有更多背景,也可能。
为了让它更整洁,你可以尝试
var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
function clickHandler (event) {
alert(prizes[this.id.replace('btn-', '')])
};
elems = document.getElementsByClassName('click-me');
for (var i=0; i<elems.length; i++) {
elems[i].onclick = clickHandler;
}
<button id="btn-0" class="click-me">Button 1!</button>
<button id="btn-1" class="click-me">Button 2!</button>
<button id="btn-2" class="click-me">Button 3!</button>
答案 4 :(得分:0)
您遇到了closure
的副作用。
闭包是保持声明它们的函数轨道的函数。在这种情况下,onclick
函数是closure
,它跟踪btnNum
变量。随着btnNum
在每次迭代后增加,onClick
函数也会更新其实现中的btnNum
,因此您每次都会看到Fresh Laundary
。
要解决此问题,您可以创建IIFE(立即调用的函数表达式)(function() {} }()
并传递btnNum
。这将限制闭包函数的范围,该函数仅引用预期的btnNum
。
<button id="btn-0">Button 1!</button>
<button id="btn-1">Button 2!</button>
<button id="btn-2">Button 3!</button>
<script type="text/javascript">
var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length; btnNum++) {
(function(btnNum) {
document.getElementById('btn-' + btnNum).onclick = function() {
alert(prizes[btnNum]);
};
})(btnNum)
}
</script>