javascript - 一个基本的 Javascript Todo 应用程序在 ForLoop 中表现得很奇怪
问题描述
我试图用 HTML、CSS 和 JS 制作自己的 TODO 应用程序。一切都按预期工作,除了这个奇怪的问题:
当我添加一个待办事项时,forloop 会将 addEventListener 放在它上面,所以当我点击它时,它将启动里面的任何代码
问题:如果我创建了多个待办事项 .. 某些项目停止工作(当我单击该项目时 addEventListener 不工作)。
就像我创建 1 个项目: item1 :工作。
如果我创建 2 个项目: item1:不工作。项目2:工作。
如果我创建 3 个项目: item1:工作。项目2:不工作。项目2:工作。...ETC。任何解释如何解决!
代码
<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
和 TY 提前。
解决方案
让我们以这个片段为例
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].addEventListener("click", function(){
var deleteIt = this.parentElement;
deleteIt.remove();
})
}
在这里,您正在运行一个循环,并且 foreach 迭代,您正在创建一个新的点击事件。这里的问题是您没有解除绑定事件。因此,在您当前的代码中,如果您单击按钮,它将触发之前触发的所有呼叫事件。
您的代码最快的解决方案是添加类似
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 不会复制事件侦听器。这解决了你的问题。
推荐阅读
- javascript - package.json 中指定的依赖项
- ios - jenkins 无法构建共享扩展 ios xcode
- javascript - jquery父子选择器返回未定义
- java - 以 ServletContext 作为参数的工厂方法与构造函数
- angular - ionic Framework 3 firebase google 身份验证
- php - 管理员 Woocommerce 产品列表页面中显示的自定义价格计算
- python - 仅从二进制文件python中的字典中读取某些键
- node.js - 未加载 require 的模块的 Jest/Istanbul 覆盖率
- android - 如何在 RecylerView 中显示来自 Android 中 Firestore 的多个集合的数据
- java - 拆分 JavaFX 控制器类