我试图制作一个简单的计算器,并尝试使用getAttribute方法检索我的自定义data- *属性后陷入困境。
我确保用于存储元素的var确实可以容纳它们
<button type="button" class="btn btn-orange" data-num="*">*</button>
var btns = document.querySelectorAll(".btn");
for(var i = 0; i < btns.length; i++){
btns[i].addEventListener("click", function(){
var number = btns[i].getAttribute("data-num");
screen.value += number;
});
}
总共有15个按钮,类为“ btn”。我检查了控制台,btns确实包含15个元素。我不明白为什么当我点击具有指定类别的任何按钮时getAttribute("data-num")
都返回未定义状态。
答案 0 :(得分:2)
您可以在函数定义内使用this
来代替btns[i]
,如下所示:
var btns = document.querySelectorAll(".btn");
for(var i = 0; i < btns.length; i++){
btns[i].addEventListener("click", function(){
var number = this.getAttribute("data-num");
screen.value += number;
});
}
基本上,您已经为每个按钮创建了click
事件函数,并且在这些函数中使用了i
。执行此函数时,它将检查i
值,该值将是循环的最后一个值,(如果您有6个.btn
类,那么i
将有6个值),因为您没有绑定{{ 1}}具有功能的当前值。因此,每次单击都会获得最后一个值,该值将破坏代码。
为避免这种情况,您可以使用上面的代码,也可以在函数中绑定变量,如下所示:
i
在这里,我们可以将var btns = document.querySelectorAll(".btn");
for(var i = 0; i < btns.length; i++){
btns[i].addEventListener("click", function(iBindededValue){
var number = btns[iBindededValue].getAttribute("data-num");
screen.value += number;
}.bind(this, i));
}
与每个函数的当前值绑定在一起,并可以使用它。您可以参考绑定函数来检查其功能。希望它能帮助您了解它的流程,干杯!
答案 1 :(得分:0)
问题是i
被突变了,但是您在事件监听器中使用了它。如果在添加事件侦听器时登录i
,则将按预期获得0, 1, 2, 3
。但是,如果您在事件监听器中登录i
,则i
总是4
,因此btns[i]
是未定义的。
只需单独保存i
或更好的btns[i]
引用,如下所示:
var btns = document.querySelectorAll(".btn");
for(var i = 0; i < btns.length; i++){
btn = btns[i];
btn.addEventListener("click", function() {
console.log(i, btns[i]); // i == 4, btns[i] == undefined !!!!
var number = btn.getAttribute("data-num");
console.log(number);
});
}
<button class='btn' data-num='0'>0</button>
<button class='btn' data-num='1'>1</button>
<button class='btn' data-num='2'>2</button>
<button class='btn' data-num='3'>3</button>