css 我无法启动JavaScript切换

stszievb  于 2023-02-14  发布在  Java
关注(0)|答案(3)|浏览(101)

我想做的是,当我点击任务时,它会有一条线穿过文本,意味着我完成了任务。但添加事件侦听器功能不起作用,我正在使用javascript切换,这是我现在能想到的实现此功能的所有方法。
有没有别的方法可以做到这一点?我在互联网上搜索,当我试图找出它似乎很复杂。

const addBtn = document.querySelector("#push");
const taskInput = document.querySelector("#taskInput");
const taskOutput = document.querySelector("#tasks");

addBtn.addEventListener("click", function() {
  let newTasks = taskInput.value;
  if (newTasks.length == 0) {
    alert("Please enter a task");
  } else {
    taskOutput.innerHTML += `<div class="task">
                <span id="taskname">${newTasks} </span>
                <button class="delete" id="deleteButton"><i class="fa-solid fa-trash"></i> </button>
    
    
            </div>
            `;
    //delete
    let deleteBtn = document.querySelector("#deleteButton");
    deleteBtn.addEventListener("click", function() {
      this.parentNode.remove();
    });
    //line through
    let theTask = document.querySelectorAll(".task");
    theTask.addEventListener("click", function() {
      this.classList.toggle("completed");
    });
  }
});
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
  background: linear-gradient( 90deg, rgba(241, 206, 221, 1) 0%, rgba(124, 184, 254, 1) 100%);
  display: flex;
  justify-content: center;
  align-items: center;
  font-family: 'Kumbh Sans', sans-serif;
}

.container {
  border: 2px solid white;
  width: 50%;
  min-width: 450px;
  margin: auto;
  padding: 30px 40px;
}

#new-task {
  position: relative;
  background-color: white;
  padding: 30px 20px;
  border-radius: 1em;
}

#new-task input {
  width: 70%;
  height: 45px;
  font-family: 'Manrope', sans-seif;
  font-size: 1.2em;
  border: 2px solid #d1d3d4;
  padding: 12px;
  color: #111111;
  font-weight: 500;
  position: relative;
  border-radius: 5px;
}

#new-task input:focus {
  outline: none;
  border-color: violet;
}

#new-task button {
  font-family: 'Manrope', sans-seif;
  position: relative;
  float: right;
  width: 25%;
  height: 45px;
  border-radius: 5px;
  font-weight: bold;
  font-size: 16px;
  border: none;
  background-color: violet;
  color: white;
  cursor: pointer;
}

#tasks {
  background-color: white;
  padding: 30px 20px;
  margin-top: 50px;
  border-radius: 10px;
  width: 100%;
}

.task {
  background-color: white;
  height: 50px;
  padding: 5px 10px;
  margin-top: 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 2px solid violet;
  cursor: pointer;
}

.task span {
  font-size: 18px;
  font-weight: 400;
}

.task button {
  background-color: violet;
  color: white;
  height: 100%;
  width: 40px;
  border: none;
  border-radius: 5px;
  outline: none;
  cursor: pointer;
}

.task button:hover {
  background-color: red;
}

.completed {
  text-decoration: line-through;
}
<body>
  <div class="container">
    <div id="new-task">
      <input type="text" name="" id="taskInput" placeholder="Task to be done" />
      <button id="push">ADD</button>
    </div>

    <div id="tasks"></div>
  </div>

  <script src="/script.js"></script>
</body>
qvk1mo1f

qvk1mo1f1#

theTask是节点列表。尝试在此列表上附加事件侦听器会导致问题。
此外,您将插入许多具有相同id deleteButton的按钮和具有相同id taskname的范围,这是不正确的,可能导致未定义的行为。
对于theTask修复,您可能需要执行以下操作:

let theTasks = [...document.querySelectorAll(".task")];
theTasks.forEach(task => {
  task.addEventListener("click", function() {
    this.classList.toggle("completed");
  })
});
eoigrqb6

eoigrqb62#

使用innerHTML为应用程序创建操作DOM(如todo列表)可能不是一个好主意,Advantages of createElement over innerHTML?的答案很好地解释了原因。
值得注意的是,在innerHTML代码中,spanbutton是用id创建的,因此所有这些元素都将具有相同的id。在一个页面上具有重复的ids也可能不是一个好主意。Why are duplicate ID values not allowed in HTML?解释了原因。
此外,为每个新任务添加事件侦听器也可能不是一个好主意。What is DOM Event delegation?给出了一个很好的解释。
最后,Difference between HTMLCollection, NodeLists, and arrays of objectsDocument.querySelectorAll()解释了如何获取可以操作的元素列表。
因此,我在addBtn.addEventListener中重写了任务创建代码,以展示如何使用document.createElement()完成此操作的一种方法。
我在Tasks容器div上创建了一个单独的事件侦听器,它处理任务删除和任务完成。
我还添加了下面的CSS,这样点击垃圾桶图标就可以由父按钮来处理,没有这个CSS,点击图标就不会删除任务。

div#tasks i {
  pointer-events: none;
}

为了使todo列表在下面的代码片段中更加可见,我减少了CSS中一些元素的heightsmarginspaddings
我还添加了一个链接到字体真棒图标库。
x一个一个一个一个x一个一个二个一个x一个一个三个一个

o7jaxewo

o7jaxewo3#

querySelectorAll将返回与选择器tasks匹配的节点列表。因此,您必须遍历每个节点并添加侦听器。

let theTasks = document.querySelectorAll(".task");
theTasks.forEach((task) => {
  task.addEventListener("click", function() {
    this.classList.toggle("completed");
  });
});

相关问题