我正在构建一个简单的计算器应用程序。我正在努力完成三件事:
使用eventListener函数显示单击按钮的值。
<span class="close"></span>
传递给事件监听器函数时,似乎无法访问btnVal。
答案 0 :(得分:1)
作业不会那样奏效。相反,请使用目标值
for (i = 0; i < btn.length; i++) {
btn[i].addEventListener("click", function(e) {
displayNumber(e.target.value)
}, false);
}
答案 1 :(得分:0)
您无法在活动中使用btnVal。
看起来应该是这样的
for (i = 0; i < btn.length; i++) {
btn[i].addEventListener("click", function(event) {
var clickedButton = event.target || event.srcElement;
console.log(clickedButton.value)
}, false);
}
答案 2 :(得分:0)
在循环内定义事件侦听器(或其他异步事物)很棘手。您可能认为自己创建了几个不同的btnVal
变量,每次循环都有一个变量,但您并非如此。 var btnVal被提升到顶部并重复使用,所以你的代码最终表现得像这样:
var btnVal;
for (i = 0; i < btn.length; i++) {
btnVal = btn[i].value;
btn[i].addEventListener("click", function() { displayNumber(btnVal) }, false);
}
因此,所有的事件侦听器都与同一个变量进行交互,当它们最终被点击时,它们只能看到分配给btnVal的最后一个值,它应该是btn[btn.length -1].value
。数组中较早的所有值都将丢失。
有几种方法可以解决这个问题:
1)当事件发生时,您可以从元素本身拉出它,而不是依赖于闭包变量。
for (i = 0; i < btn.length; i++) {
btn[i].addEventListener("click", function (event) {
displayNumber(event.target.value);
});
}
2)将事件监听器创建移动到一个函数中,并传入btnVal。由于它现在是一个函数参数,它将获得一个新的绑定。
for (i = 0; i < btn.length; i++) {
createListener(btn[i], btn[i].value);
}
function createListener(element, val) {
element.addEventListener("click", function () { displayNumber(val) }, false);
}
3)您可以使用IIFE进行内联。
for (i = 0; i < btn.length; i++) {
(function (button) {
button.addEventListener("click", function () { displayNumber(button.value) }, false);
})(btn[i]);
}
编辑:添加了选项4
4)如果您可以使用ES2015,请使用let
。让我们阻止范围,并且每次通过循环都会得到一个新的绑定
for (i = 0; i < btn.length; i++) {
let btnVal = btn[i].value;
btn[i].addEventListener("click", function() { displayNumber(btnVal) }, false);
}