我是JavaScript语言的新手,请帮助我了解该问题出了哪些问题。 我正在尝试单击列表项时打开和关闭完成的类。但是我遇到了“未捕获的TypeError:无法读取HTMLLIElement处未定义的属性'classList'”错误。
var li = document.querySelectorAll("li");
for (var i = 0; i < li.length; i++) {
li[i].addEventListener("click", function() {
li[i].classList.toggle("done");
})
}
.done {
text-decoration: line-through;
}
<h1>Shopping List</h1>
<ul style="list-style-type:square">
<li>Pencil</li>
<li>Paper</li>
<li>Eraser</li>
<li>Table Lamp</li>
<li>Comb</li>
</ul>
答案 0 :(得分:1)
更改
li[i].classList.toggle("done");
到
this.classList.toggle("done");
...否则,在事件回调中,您将始终以li
的最后一个值表示的i
为目标,而不是被单击的那个。
答案 1 :(得分:1)
要提高代码的性能,可以使用事件委托。使用这种技术,您只需要向容器(在本例中为ul)中添加一次侦听器,所有子代都可以访问它。然后,您可以使用 event.target 属性定位每个li项目:
var ul = document.querySelector("ul");
ul.addEventListener('click', function(event){
event.target.classList.toggle("done");
});
答案 2 :(得分:0)
添加事件监听器时,您正在创建一个闭包。每个事件处理程序在其作用域内都有变量i
。不幸的是,它是相同的变量i
,由您的for循环递增。
在循环结束时,每个事件处理程序在其作用域内都有一个变量i
,其值现在为6。这将导致在触发事件时未定义li[i]
。
您可以通过以下方法解决此问题:
i
,例如,通过使用提供的event
变量来引用事件。然后,检索目标元素:
var li = document.querySelectorAll("li");
for (var i = 0; i < li.length; i++) {
li[i].addEventListener("click", function(event) {
event.target.classList.toggle("done");
})
}
.done {
text-decoration: line-through;
}
<h1>Shopping List</h1>
<ul style="list-style-type:square">
<li>Pencil</li>
<li>Paper</li>
<li>Eraser</li>
<li>Table Lamp</li>
<li>Comb</li>
</ul>
i
而不是let
声明var
。这将导致您的每个闭包与i
具有不同的绑定:
var li = document.querySelectorAll("li");
for (let i = 0; i < li.length; i++) {
li[i].addEventListener("click", function() {
li[i].classList.toggle("done");
})
}
.done {
text-decoration: line-through;
}
<h1>Shopping List</h1>
<ul style="list-style-type:square">
<li>Pencil</li>
<li>Paper</li>
<li>Eraser</li>
<li>Table Lamp</li>
<li>Comb</li>
</ul>
var ul = document.querySelector("ul");
ul.addEventListener("click", function(event) {
event.target.classList.toggle("done");
}, true);
.done {
text-decoration: line-through;
}
<h1>Shopping List</h1>
<ul style="list-style-type:square">
<li>Pencil</li>
<li>Paper</li>
<li>Eraser</li>
<li>Table Lamp</li>
<li>Comb</li>
</ul>
答案 3 :(得分:0)
//using for of loop
var li = document.querySelectorAll("li");
for (var i of li) {
i.addEventListener('click', function(e) {
e.target.classList.toggle("done");
})
}
.done {
text-decoration: line-through;
}
<h1>Shopping List</h1>
<ul style="list-style-type:square">
<li>Pencil</li>
<li>Paper</li>
<li>Eraser</li>
<li>Table Lamp</li>
<li>Comb</li>
</ul>