我正在尝试制作一个简单的计算器,但在尝试使用 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")
返回未定义。
您可以在函数定义中使用
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函数来检查其功能。希望它能帮助您理解其流程,干杯!!
问题是
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>
我来到这个页面时遇到了完全相同的问题!在尝试了建议并得到相同的错误后,我重新检查了我正在使用的数据项。因为我正在做一个日记项目,所以我的有日期:
<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 和数据项中删除所有标点符号。