我正在尝试使用HTML,CSS和JS制作自己的TODO应用程序。一切都按预期工作,解决了这个奇怪的问题:
当我添加待办事项时,forloop会在其上添加addEventListener,因此当我单击它时,它将启动内部的任何代码
问题:如果我创建多个待办事项..一些项目停止工作(当我单击该项目时addEventListener不起作用)。
就像我创建1个项目一样: item1:正在工作。
如果我创建2个项目: item1:不起作用。 item2:正在工作。
如果我创建3个项目: item1:正在工作。 item2:不起作用。 item2:正在工作。 ...等等。 任何说明如何解决!
HTML代码
<div id="form">
<p id="error">Fill The Empty !</p>
<input id="input" type="text" placeholder="Text Here!" >
<button id="add" type="submit" onclick="addIt()">Add</button>
</div>
<div id="listContainer">
<ul id="list">
</ul>
<p id="noItems">You Have No Items!</p>
</div>
CSS代码
margin: 0px;
padding: 0px;
font-family: monospace, sans-serif;
list-style: none;
font-size: 10pt;
box-sizing: border-box;
}
#form{
display: flex;
flex-direction: column;
justify-content: center;
align-items:center;
}
#error{
color: red;
display: none;
margin: 5px 0px;
}
#input{
width: 95%;
height: 40px;
text-align: center;
margin: 5px 0px;
border: 1px purple dashed;
}
#add{
height: 40px;
width: 95%;
border: 0px;
color: white;
background-color: purple;
font-weight: 900;
}
#add:active{
color: purple;
background-color: white;
}
#listContainer{
margin-top: 40px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100vw;
}
#list{
display: flex;
flex-direction: column-reverse;
justify-content: center;
align-items: center;
width: 100vw;
}
.item{
position: relative;
text-align: center;
padding: 10px;
margin: 5px;
width: 95%;
color: purple;
background-color: white;
border: 1px purple solid;
font-size: 11pt;
}
.delete{
position: absolute;
right: 0px;
top: 0px;
padding: 10px;
width: 50px;
color: white;
background-color: red;
font-size: 11pt;
font-weight: 900;
}
#noItems{
color: lightgray;
margin-top: 50px;
/*display: none;*/
}
JS代码
let storeInput = "";
function addIt(){
/*---addIT() start---*/
let input = document.getElementById("input");
storeInput = input.value;
if(storeInput == ""){
let errorMsg = document.getElementById("error");
errorMsg.style.display = "block";
setTimeout(function(){errorMsg.style.display = "none";}, 2000)
}else{
input.value = "";
let item = document.createElement("LI");
item.className = "item";
item.innerHTML = storeInput;
let list = document.getElementById("list");
list.appendChild(item);
let deleteIt = document.createElement("I");
deleteIt.className = "delete";
deleteIt.innerHTML = "X";
item.appendChild(deleteIt);
}
let allItems = document.querySelectorAll(".item");
for(var i = 0; i < allItems.length; i++){
allItems[i].addEventListener("click", function(){
if(this.style.textDecoration == "line-through"){
this.style.textDecoration = "none";
}else{
this.style.textDecoration = "line-through";
}
})
}
let deleteItem = document.querySelectorAll(".delete");
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].addEventListener("click", function(){
var deleteIt = this.parentElement;
deleteIt.remove();
})
}
document.querySelectorAll(".item").length;
if(allItems.length == 0){
document.getElementById("noItems").style.display = "block";
}else{
document.getElementById("noItems").style.display = "none";
}
/*---addIT() end---*/}
如果您想实时试用该应用程序: https://codepen.io/Salsa_Project/pen/NVWPaY?editors=0110
提前付款。
答案 0 :(得分:1)
让我们以该代码段为例
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].addEventListener("click", function(){
var deleteIt = this.parentElement;
deleteIt.remove();
})
}
在这里,您正在运行一个循环,并且对于每次迭代,您都在创建一个新的click事件。这里的问题是您没有解除绑定的事件。因此,在当前代码中,如果单击该按钮,它将触发所有先前触发的呼叫事件。
最快的代码解决方案是添加
let deleteItem = document.querySelectorAll(".delete");
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].parentNode.replaceChild(deleteItem[j].cloneNode(true), deleteItem[j]);
})
}
deleteItem = document.querySelectorAll(".delete");
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].addEventListener("click", function(){
var deleteIt = this.parentElement;
deleteIt.remove();
})
}
请注意
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].parentNode.replaceChild(deleteItem[j].cloneNode(true), deleteItem[j]);
})
}
将用其自身替换当前元素。唯一的区别是cloneNode不复制事件侦听器。这样可以解决您的问题。
答案 1 :(得分:1)
函数addit()会在所有元素上添加事件监听器,并在每次添加元素时删除按钮。您只应将事件侦听器添加到当前项目。 codepen
let storeInput = "";
function addIt(){
/*---addIT() start---*/
let input = document.getElementById("input");
storeInput = input.value;
if(storeInput == ""){
let errorMsg = document.getElementById("error");
errorMsg.style.display = "block";
setTimeout(function(){errorMsg.style.display = "none";}, 2000)
}else{
input.value = "";
let item = document.createElement("LI");
item.className = "item";
item.innerHTML = storeInput;
let list = document.getElementById("list");
list.appendChild(item);
let deleteIt = document.createElement("I");
deleteIt.className = "delete";
deleteIt.innerHTML = "X";
item.appendChild(deleteIt);
item.addEventListener("click", function(){
if(this.style.textDecoration == "line-through"){
this.style.textDecoration = "none";
}else{
this.style.textDecoration = "line-through";
}
});
deleteIt.addEventListener("click", function(){
var deleteIt = this.parentElement;
deleteIt.remove();
})
}
let allItems = document.querySelectorAll(".item");
document.querySelectorAll(".item").length;
if(allItems.length == 0){
document.getElementById("noItems").style.display = "block";
}else{
document.getElementById("noItems").style.display = "none";
}
/*---addIT() end---*/}