javascript - for 循环 - 仅每隔一个事件侦听器工作
javascript - for loop - only every second event listener working
我是网页设计的新手,所以我确定我在这里做了一些愚蠢的事情,但我真的很好奇我做错了什么,我正在做一个在线 udemy 课程,出于某种原因,li 的每两次迭代我 spawn 似乎附加了我的事件侦听器,但我终究无法弄清楚原因。我假设在添加事件侦听器时它与我的“this”有关,我试图更改为 listObjects[i].classList.toggle 但它只是抛出了一个错误但是奇怪的是如果我做 this.classList.add("完成") 它完美地工作。提前致谢!
var enterBtn = document.querySelectorAll("button")[0];
var cancelBtn = document.querySelectorAll("button")[1];
var ul = document.querySelector("ul");
var listObjects
function addList(todo) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(todo));
ul.appendChild(li);
listObjects = document.querySelectorAll("li");
setListDone();
}
enterBtn.addEventListener("click", function() {
var listData = document.querySelector("input").value;
addList(listData);
});
cancelBtn.addEventListener("click", function() {
ul.innerHTML = " ";
});
function setListDone() {
for (i = 0; i < listObjects.length; i++) {
listObjects[i].addEventListener("click", function() {
this.classList.toggle("done");
});
}
}
.done {
text-decoration: line-through;
}
<h1>Todo List</h1>
<input type="text">
<button>Enter</button>
<button>Cancel</button>
<ul>
</ul>
您永远不会删除旧的事件侦听器,因此具有偶数索引的任何内容都会被切换两次(或四次,或其他),并以与开始时相同的状态结束。如果您先清除旧的事件侦听器(或仅将它们添加到新创建的元素),问题就会消失:
var enterBtn = document.querySelectorAll("button")[0];
var cancelBtn = document.querySelectorAll("button")[1];
var ul = document.querySelector("ul");
var listObjects
function addList(todo) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(todo));
ul.appendChild(li);
listObjects = document.querySelectorAll("li");
setListDone();
}
enterBtn.addEventListener("click", function() {
var listData = document.querySelector("input").value;
addList(listData);
});
cancelBtn.addEventListener("click", function() {
ul.innerHTML = " ";
});
function setListDone() {
for (i = 0; i < listObjects.length; i++) {
listObjects[i].removeEventListener("click", liClickHandler);
listObjects[i].addEventListener("click", liClickHandler);
}
}
function liClickHandler() {
this.classList.toggle("done");
}
.done {
text-decoration: line-through;
}
<h1>Todo List</h1>
<input type="text">
<button>Enter</button>
<button>Cancel</button>
<ul>
</ul>
原因是您正在使用 setListDone
将 click
分配给所有 li
。因此,当您添加第二个 li
时,它也会将 click
分配给 first
li
。所以当你点击第一个 li
时,它会调用 click
twice
。此外,如果您添加第三个 li
然后在 first
li
上单击它将调用 click
three times
.
要解决问题,您只需将新创建的 li
传递给 setListDone
并如下更新您的 setListDone
。
function setListDone(li) {
li.addEventListener("click", function() {
this.classList.toggle("done");
});
}
测试下面的完整代码。
var enterBtn = document.querySelectorAll("button")[0];
var cancelBtn = document.querySelectorAll("button")[1];
var ul = document.querySelector("ul");
var listObjects
function addList(todo) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(todo));
ul.appendChild(li);
listObjects = document.querySelectorAll("li");
setListDone(li);
}
enterBtn.addEventListener("click", function() {
var listData = document.querySelector("input").value;
addList(listData);
});
cancelBtn.addEventListener("click", function() {
ul.innerHTML = " ";
});
function setListDone(li) {
li.addEventListener("click", function() {
this.classList.toggle("done");
});
}
.done {
text-decoration: line-through;
}
<h1>Todo List</h1>
<input type="text">
<button>Enter</button>
<button>Cancel</button>
<ul>
</ul>
每次将项目添加到列表时,您都会为每个项目添加事件侦听器。这就是为什么其中一些会被触发两次或更多次的原因。
listObjects[i].addEventListener("click", function() {
this.classList.toggle("done");
});
简单的解决方案如下。
每次向列表添加元素时,您只需要将事件侦听器添加到 单个 <li>
。
var enterBtn = document.querySelectorAll("button")[0];
var cancelBtn = document.querySelectorAll("button")[1];
var ul = document.querySelector("ul");
var listObjects
function addList(todo) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(todo));
// Here you add the listener to just created list item
li.addEventListener("click", function() {
this.classList.toggle("done");
});
ul.appendChild(li);
}
enterBtn.addEventListener("click", function() {
var listData = document.querySelector("input").value;
addList(listData);
});
cancelBtn.addEventListener("click", function() {
ul.innerHTML = " ";
});
.done {
text-decoration: line-through;
}
<h1>Todo List</h1>
<input type="text">
<button>Enter</button>
<button>Cancel</button>
<ul>
</ul>
我是网页设计的新手,所以我确定我在这里做了一些愚蠢的事情,但我真的很好奇我做错了什么,我正在做一个在线 udemy 课程,出于某种原因,li 的每两次迭代我 spawn 似乎附加了我的事件侦听器,但我终究无法弄清楚原因。我假设在添加事件侦听器时它与我的“this”有关,我试图更改为 listObjects[i].classList.toggle 但它只是抛出了一个错误但是奇怪的是如果我做 this.classList.add("完成") 它完美地工作。提前致谢!
var enterBtn = document.querySelectorAll("button")[0];
var cancelBtn = document.querySelectorAll("button")[1];
var ul = document.querySelector("ul");
var listObjects
function addList(todo) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(todo));
ul.appendChild(li);
listObjects = document.querySelectorAll("li");
setListDone();
}
enterBtn.addEventListener("click", function() {
var listData = document.querySelector("input").value;
addList(listData);
});
cancelBtn.addEventListener("click", function() {
ul.innerHTML = " ";
});
function setListDone() {
for (i = 0; i < listObjects.length; i++) {
listObjects[i].addEventListener("click", function() {
this.classList.toggle("done");
});
}
}
.done {
text-decoration: line-through;
}
<h1>Todo List</h1>
<input type="text">
<button>Enter</button>
<button>Cancel</button>
<ul>
</ul>
您永远不会删除旧的事件侦听器,因此具有偶数索引的任何内容都会被切换两次(或四次,或其他),并以与开始时相同的状态结束。如果您先清除旧的事件侦听器(或仅将它们添加到新创建的元素),问题就会消失:
var enterBtn = document.querySelectorAll("button")[0];
var cancelBtn = document.querySelectorAll("button")[1];
var ul = document.querySelector("ul");
var listObjects
function addList(todo) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(todo));
ul.appendChild(li);
listObjects = document.querySelectorAll("li");
setListDone();
}
enterBtn.addEventListener("click", function() {
var listData = document.querySelector("input").value;
addList(listData);
});
cancelBtn.addEventListener("click", function() {
ul.innerHTML = " ";
});
function setListDone() {
for (i = 0; i < listObjects.length; i++) {
listObjects[i].removeEventListener("click", liClickHandler);
listObjects[i].addEventListener("click", liClickHandler);
}
}
function liClickHandler() {
this.classList.toggle("done");
}
.done {
text-decoration: line-through;
}
<h1>Todo List</h1>
<input type="text">
<button>Enter</button>
<button>Cancel</button>
<ul>
</ul>
原因是您正在使用 setListDone
将 click
分配给所有 li
。因此,当您添加第二个 li
时,它也会将 click
分配给 first
li
。所以当你点击第一个 li
时,它会调用 click
twice
。此外,如果您添加第三个 li
然后在 first
li
上单击它将调用 click
three times
.
要解决问题,您只需将新创建的 li
传递给 setListDone
并如下更新您的 setListDone
。
function setListDone(li) {
li.addEventListener("click", function() {
this.classList.toggle("done");
});
}
测试下面的完整代码。
var enterBtn = document.querySelectorAll("button")[0];
var cancelBtn = document.querySelectorAll("button")[1];
var ul = document.querySelector("ul");
var listObjects
function addList(todo) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(todo));
ul.appendChild(li);
listObjects = document.querySelectorAll("li");
setListDone(li);
}
enterBtn.addEventListener("click", function() {
var listData = document.querySelector("input").value;
addList(listData);
});
cancelBtn.addEventListener("click", function() {
ul.innerHTML = " ";
});
function setListDone(li) {
li.addEventListener("click", function() {
this.classList.toggle("done");
});
}
.done {
text-decoration: line-through;
}
<h1>Todo List</h1>
<input type="text">
<button>Enter</button>
<button>Cancel</button>
<ul>
</ul>
每次将项目添加到列表时,您都会为每个项目添加事件侦听器。这就是为什么其中一些会被触发两次或更多次的原因。
listObjects[i].addEventListener("click", function() {
this.classList.toggle("done");
});
简单的解决方案如下。
每次向列表添加元素时,您只需要将事件侦听器添加到 单个 <li>
。
var enterBtn = document.querySelectorAll("button")[0];
var cancelBtn = document.querySelectorAll("button")[1];
var ul = document.querySelector("ul");
var listObjects
function addList(todo) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(todo));
// Here you add the listener to just created list item
li.addEventListener("click", function() {
this.classList.toggle("done");
});
ul.appendChild(li);
}
enterBtn.addEventListener("click", function() {
var listData = document.querySelector("input").value;
addList(listData);
});
cancelBtn.addEventListener("click", function() {
ul.innerHTML = " ";
});
.done {
text-decoration: line-through;
}
<h1>Todo List</h1>
<input type="text">
<button>Enter</button>
<button>Cancel</button>
<ul>
</ul>