如何解决“无法读取未定义的属性'getAttribute'?

时间:2019-08-15 14:48:58

标签: javascript html custom-data-attribute

我试图制作一个简单的计算器,并尝试使用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")都返回未定义状态。

2 个答案:

答案 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>