一个基本的Javascript Todo应用程序在ForLoop中表现得很奇怪

一个基本的Javascript Todo应用程序在ForLoop中表现得很奇怪,javascript,arrays,for-loop,Javascript,Arrays,For Loop,我试图用HTML、CSS和JS制作自己的TODO应用程序。。一切正常,除了这个奇怪的问题: 当我添加一个todo项时,forloop将在其上放置addEventListener,因此当我单击它时,它将启动其中的任何代码 问题:如果我创建了多个待办事项。。某些项停止工作(单击该项时addEventListener不工作) 如果我创建一个项目: 项目1:工作 如果我创建两个项目: 项目1:不工作。 项目2:工作 如果我创建3个项目: 项目1:工作。 项目2:不工作。 项目2:工作。 等 任何关于如何

我试图用HTML、CSS和JS制作自己的TODO应用程序。。一切正常,除了这个奇怪的问题:

当我添加一个todo项时,forloop将在其上放置addEventListener,因此当我单击它时,它将启动其中的任何代码

问题:如果我创建了多个待办事项。。某些项停止工作(单击该项时addEventListener不工作)

如果我创建一个项目: 项目1:工作

如果我创建两个项目: 项目1:不工作。 项目2:工作

如果我创建3个项目: 项目1:工作。 项目2:不工作。 项目2:工作。 等 任何关于如何修复的解释

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>
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---*/}
let storeInput=“”;
函数addIt(){
/*---addIT()开始---*/
让输入=document.getElementById(“输入”);
storeInput=input.value;
如果(storeInput==“”){
让errorMsg=document.getElementById(“错误”);
errorMsg.style.display=“块”;
setTimeout(function(){errorMsg.style.display=“none”;},2000)
}否则{
input.value=“”;
让item=document.createElement(“LI”);
item.className=“item”;
item.innerHTML=storeInput;
let list=document.getElementById(“list”);
列表。追加子项(项目);
让deleteIt=document.createElement(“I”);
deleteIt.className=“删除”;
deleteIt.innerHTML=“X”;
项目.appendChild(删除它);
}
让allItems=document.queryselectoral(“.item”);
对于(变量i=0;i
如果您想尝试应用程序live:


并且提前准备好。

让我们以这个snippit为例

  for(var j = 0; j < deleteItem.length; j++){
    deleteItem[j].addEventListener("click", function(){
      var deleteIt = this.parentElement;
      deleteIt.remove();
    })
  }
for(var j=0;j
在这里,您正在运行一个循环,对于每个迭代,您正在创建一个新的单击事件。这里的问题是你没有解开束缚的事件。因此,在您当前的代码中,如果您单击该按钮,它将触发以前触发的所有调用事件

代码的最快解决方案是添加以下内容

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();
    })
  }
let deleteItem=document.querySelectorAll(“.delete”);
对于(var j=0;j
注意

  for(var j = 0; j < deleteItem.length; j++){
     deleteItem[j].parentNode.replaceChild(deleteItem[j].cloneNode(true), deleteItem[j]);
    })
  }
for(var j=0;j

将用自身替换当前元素。唯一的区别是cloneNode不复制事件侦听器。这解决了您的问题。

让我们以这个snippit为例

  for(var j = 0; j < deleteItem.length; j++){
    deleteItem[j].addEventListener("click", function(){
      var deleteIt = this.parentElement;
      deleteIt.remove();
    })
  }
for(var j=0;j
在这里,您正在运行一个循环,对于每个迭代,您正在创建一个新的单击事件。这里的问题是你没有解开束缚的事件。因此,在您当前的代码中,如果您单击该按钮,它将触发以前触发的所有调用事件

代码的最快解决方案是添加以下内容

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();
    })
  }
let deleteItem=document.querySelectorAll(“.delete”);
对于(var j=0;j
注意

  for(var j = 0; j < deleteItem.length; j++){
     deleteItem[j].parentNode.replaceChild(deleteItem[j].cloneNode(true), deleteItem[j]);
    })
  }
for(var j=0;j
将用自身替换当前元素。唯一的区别是cloneNode不复制事件侦听器。这就解决了您的问题。

每次添加元素时,函数addit()都会将eventlisteners添加到所有项目中,并删除按钮。您应该只向当前项添加eventlisteners

每次添加元素时,函数addit()会将eventlisteners添加到所有项和删除按钮。您应该只向当前项添加eventlisteners


请在您的答案中添加相关代码,以展示正确答案。编辑不接受笔下的代码。对空格等问题唠叨不休然后链接到pen/jsfiddle无论链接在那里是什么,但是编辑不接受没有背景标记的链接。哇,现在我完全理解了这个问题..t请在你的答案中添加相关代码,以展示正确的答案编辑器不接受来自pen的代码。对空格等问题唠叨不休当链接到pen/jsfiddle时,不管链接在那里是什么,但是编辑不接受没有背景标记的链接。哇,现在我明白了问题的确切含义。太详细了,太详细了