如何修复“无法读取未定义的属性‘getAttribute’?

问题描述 投票:0回答:3

我正在尝试制作一个简单的计算器,但在尝试使用 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;
    });
}

class=“btn”的按钮一共有15个。我检查过控制台,btns 确实包含 15 个元素。我不明白为什么当我单击任何具有指定类的按钮时

getAttribute("data-num")
返回未定义。

javascript html custom-data-attribute
3个回答
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 个),因为您没有将
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));
}

在这里我们可以将

i
与每个函数的当前值绑定并可以使用它。您可以参考bind函数来检查其功能。希望它能帮助您理解其流程,干杯!!


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>


0
投票

我来到这个页面时遇到了完全相同的问题!在尝试了建议并得到相同的错误后,我重新检查了我正在使用的数据项。因为我正在做一个日记项目,所以我的有日期:

    <pre>
        <li data-date="#01/01/1900">The Past</li>
        <li data-date="#01/04/1994">Apr '94</li>
        <li data-date="#01/10/1996" class="selected">Oct '96</li>
        <li data-date="#01/09/2005">Sep '05</li>
    </pre>

这些旨在与包含更多信息的第二个列表保持一致:

    <pre>
        <li id="01/01/1900">
        <li id="01/04/1994">
        <li id="01/10/1996" class="selected">
        <li id="01/09/2005">
    </pre>

我知道我有正确的选择器和事件监听器,因为我之前使用过类似的代码:

但是错误仍然存在!

只有当我尝试将数据日期和 ID 项更改为简单的“第一”、“第二”、“第三”、“第四”等时,错误才消失,并且我的代码按预期工作。

    <pre>
            const events = document.querySelectorAll(".events ol li");

            events.forEach((event) => {
                event.addEventListener("click", () => {
  
                    const eventDate = this.getAttribute("data-date");
                    const eventInfo = document.querySelector(eventDate);

                    console.log(eventDate);
                    console.log(eventInfo);
                });
            });
    </pre>

结论:从您的 ID 和数据项中删除所有标点符号。

© www.soinside.com 2019 - 2024. All rights reserved.