在执行同一 js 文件中定义的另一个事件处理函数后,一个事件处理函数未被触发

One event handler function not getting triggered after the execution of another event handler function defined in the same js file

我正在尝试构建一个静态待办事项应用程序,此应用程序将待办事项列表存储在 localStorage(浏览器内存)中。

有 3 个元素与错误相关 - 1 个元素导致错误,另外 2 个元素受错误影响。

  1. 隐藏完成复选框 - 选中时隐藏已完成的任务。 (导致错误的元素)
  2. 完成待办事项复选框 - 选中后将待办事项标记为已完成。
  3. 删除备注按钮 - 删除备注。

我附上了代码文件和屏幕截图,以便对问题和代码有一个整体的了解。 与此同时,我将我的代码存储在这个 repo 中:https://github.com/AbhishekTomr/Todo

问题 - 一旦隐藏完成复选框被触发,完成待办事项和删除待办事项机制将停止工作。

有人可以帮我修复代码或让我知道是什么导致了这个问题吗?

截图:

//js file : todoFunctions.js 

//function for getting value stored in todoList
let getTodo = function(){
    return Boolean(localStorage.getItem("todo"))?JSON.parse(localStorage.getItem("todo")):[];
}

//function to add or render any list on the screen
let render = function(list){
    document.querySelector("#td").innerHTML = "";
    list.forEach(function(item){
        newTask(item);
        }
    )
}

//function for saving the task in the local storage
let saveTask = function(todo){
    let tdList = JSON.stringify(todo);
    localStorage.setItem("todo",tdList); //setting value for the first time or updating it
}


let newTask = function(node)
{
    let li = document.createElement("li");
    let status = document.createElement("input");
    let remove = document.createElement("button");
    li.textContent = node.td;

    remove.setAttribute("class","remove");
    remove.textContent="Delete";
    

    status.setAttribute("type","checkbox");
    status.setAttribute("class","status");
    status.checked = node.status;
    li.style.textDecoration = (node.status)?"line-through":"none";

    let div = document.createElement("div");
    div.setAttribute("class","task");
    div.setAttribute("id",node.index);



    div.appendChild(status);
    div.appendChild(li);
    div.appendChild(remove);
    document.querySelector("#td").appendChild(div);

    document.getElementById("new-task").value = ""; //clearing the input feild

}

//function for adding a new task
let addTask = function(todo){
    let td = document.getElementById("new-task").value;
    let status = false;
    let node = {td : td,status : status};
    todo.push(node);
    saveTask(todo); // saving it to local storage
    newTask(node);
}

// function for searching out task
let searchTask = function(todo,e){
    let searchList = todo.filter(function(item){
        return item.td.includes(e.target.value);
    })
    render(searchList); // showing the searched terms on the go..
}


//funtion to delete task
let deleteTodo=function(e,index,todo){
    e.target.parentElement.remove();
    todo.splice(index,1);
    saveTask(todo);
}

//funtion for completing and undoing a task
let changeStatus = function(e,index,todo){
    let state = e.target.checked;
    let td = e.target.parentElement.children[1];
    td.style.textDecoration = (state)?"line-through":"none";
    todo[index].status = state;
    saveTask(todo);
}

//function for hiding complete task
let hideCompleted = function(e,todo){
    if(e.target.checked)
    {
        let filterLst = todo.filter(function(item){
            return !item.status;
        })
     render(filterLst);
    }else{
        render(todo);
    }

}


//js file :main.js
let todo = getTodo(); // get the todo List from storage
render(todo); // display the initial todo List 

//functionality for the different events

document.getElementById("add-task").addEventListener("click",function(e){ //event when the add new task button is pressed
    addTask(todo);  //funtion for adding new task and displaying it on page
})

document.getElementById("search-txt").addEventListener("input",function(e){ //event for text typed in seach bar
    searchTask(todo,e); //funtion for searching the tasks and displaying it on page
})




//event to delete todo 
let btns = document.querySelectorAll(".remove");
btns.forEach(function(item,index){
    item.addEventListener("click",function(e){
        deleteTodo(e,index,todo);
    })
})

//event for complete/uncomplete task
let check = document.querySelectorAll(".status");
check.forEach(function(item,index){
    item.addEventListener("change",function(e){
        changeStatus(e,index,todo);
        console.log("i am triggered");
    })
})

document.querySelector("#hide-check").addEventListener("change",function(e){  //event when hide completed is checked and unchecked
   hideCompleted(e,todo);
})
/* css file : main.css */

*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  /* border: 1px solid black; */
  font-family: monospace;
}
main{
  margin: 5px;
}
h1{

  font-size: 3rem;
  font-weight: bold;
  font-variant: small-caps;
  display: inline-block;
  width: 250px;
  text-align: center;
}
#td-options{
  display: flex;
  flex-flow: column nowrap;
  justify-content:space-around;
  align-items: flex-start;
  font-size: 1.2rem;
  width: 250px;
}
#search,#search input{
  width: 100%;
  height: 100%;
  text-align: center;
  border: 2px solid black;
}
#hide-completed{
  width: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  font-size: 1.2rem;
  margin: 5px 0;
}
#hide-check{
  margin: 10px;
}
#todo{
  /* border: 3px solid pink; */
  background-color: pink;
  margin: 1rem 0;
  display: inline-block;
  padding: 10px;
}
.task{
  border: 1px solid green;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  font-size: 1.2rem;
}
.task li{
  list-style-position: inside;
  margin: .5rem;
  text-transform: capitalize;
}
.task button{
  padding: 0 .5rem;
  border-radius: 2px;
  background-color: gray;
  color: whitesmoke;
}
.task button:hover{
  cursor: pointer;
}
#add-todo{
  display: flex;
  flex-flow: row nowrap;
  width: 255px;
  justify-content: space-between;
  height: 25px;
}
#add-todo button{
  padding: 0 .5rem;
  border-radius: 3px;
}
<!-- html file: index.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="main.css">
    <title>Todo</title>
</head>
<body>
    <main>
        <!-- mainheading -->
        <h1>My Todo App</h1>

        <!--todoOptions-->
        <div id="td-options">
            <div id="search">
                <input type="text" id="search-txt" placeholder="search your Todo">
            </div>
            <div id="hide-completed">
                <label for="hide-check">
                  Hide Completed Tasks
                </label>
                <input type="checkbox" id="hide-check" name="hide">
            </div>
        </div>

        <!-- todo list -->
        <div id="todo">
                <ol id="td"></ol>
        </div>

        <!-- add todo -->
        <div id="add-todo">
            <input type="text" placeholder="Add A New To Do Task" id="new-task">
            <button id="add-task">Add ToDo</button>
        </div>

        <!-- js files -->
        <script src="todoFunctions.js"></script>
        <script src="main.js"></script>
    </main>
</body>
</html>

render 函数遍历一个列表并为任务创建相关元素以将其显示在屏幕上,然后附加它们。

开始时从 localstorage 收集一个列表,然后添加所有必需的事件侦听器。

调用 hideCompleted 时,它会根据剩余未完成的元素创建一个列表,或者只使用完整的待办事项列表,然后重新呈现它。这会创建所有元素,因此屏幕上的一切看起来都很好。

但是没有添加任何事件侦听器,因此删除按钮等不会执行任何操作。

我的建议是将 .remove 等的事件侦听器创建代码制作成一个函数。在启动时以及在屏幕上重新创建列表时调用它。