使用 javascript 添加已检查的类

Adding checked class using javascript

提问人:Joyal Jijo 提问时间:11/13/2023 最后编辑:VLAZJoyal Jijo 更新时间:11/14/2023 访问量:54

问:

我尝试使用事件侦听器将检查类添加到待办事项列表项目中。但是,事件侦听器并没有附加到每个复选框类。代码如下

export default function (){
    const checkedElements = document.querySelectorAll(".checkbox");
    checkedElements.forEach(element => {
        element.addEventListener('click', () => {
            element.classList.toggle('checked');
        });
    });
}

这是网站 https://joyal-jij0.github.io/todo-list/,这是回购 https://github.com/joyal-jij0/todo-list.git。尝试在创建 2-4 个待办事项后单击每个复选框。我希望每个复选框都会获得事件侦听器,但有些正在获取,有些正在删除。

javascript dom-事件

评论

0赞 mplungjan 11/13/2023
请访问帮助中心参观以查看内容和如何提问。做一些研究。如果您遇到困难,请发布您的尝试的最小可重现示例,并使用 [<>] 片段编辑器 HERE 而不是外部站点记录输入和预期输出。

答:

1赞 AKX 11/13/2023 #1

您的代码正在从 addTask 调用已检查的函数

由于该函数在内部循环遍历所有复选框并添加处理程序,因此它们将具有多个单击处理程序,然后将多次来回切换选中状态。(如果将策略添加到处理程序中,则可以看到这一点。checkedconsole.log()

您还可以在浏览器检查器的 Event Listeners 列表中看到这些多个处理程序;这是我添加 4 个项目后的第一个复选框。

enter image description here

哎呀,你只需要为每个新复选框添加一次处理程序。

评论

0赞 mplungjan 11/13/2023
我强烈建议使用授权而不是循环
0赞 AKX 11/13/2023
确定。这里没有建议循环。
2赞 mplungjan 11/13/2023 #2
  1. ID 必须是唯一的。
  2. 通过最近使用委派和相对访问

document.getElementById('tasks').addEventListener('click', (e) => {
  const tgt = e.target;
  const btn = tgt.closest('button');
  const del = tgt.closest('div.delete');
  const chk = tgt.matches(".checkbox");
  if (btn) {
    if (btn.matches('.save')) {
      console.log('save');
    } else if (btn.matches('.cancel')) {
      console.log('cancel');
    }
  }
  else if (del) {
    tgt.closest('div.task').remove()
  }
  else if (chk) {
    tgt.classList.toggle('checked');
  }
});
.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
  color: hsla(0, 0%, 100%, .9);
}

i {
  color: red;
  cursor: pointer;
}

.leftContainer {
  background-color: #373c3f;
  height: 100vh;
}

.rightContainer {
  background-color: #2f3437;
  height: 100vh;
}

.projects {
  font-size: 32px;
  font-weight: bold;
  font-family: sf-bold sans-serif;
  padding-bottom: 15px;
  border-bottom: solid hsla(0, 0%, 100%, .9);
  margin: 100px 40px 20px 60px;
}

.project {
  margin-left: 60px;
  font-size: 24px;
  background-color: #444a4d;
  margin-right: 30px;
  display: flex;
  justify-content: space-between;
  padding: 10px 20px 10px 10px;
}

.addProject {
  margin-left: 200px;
  font-size: 20px;
  font-family: sf-medium sans-serif;
  margin-top: 30px;
  cursor: pointer;
}

.header {
  margin-top: 9vh;
  display: grid;
  grid-template-columns: 15fr 1fr;
  border-bottom: solid hsla(0, 0%, 100%, .9);
  margin-left: 50px;
  margin-right: 50px;
  font-size: 40px;
  font-family: sf-bold sans-serif;
  font-weight: bold;
}

.task {
  font-size: 30px;
  margin-top: 12px;
  padding: 15px;
  border-radius: 5px;
  border: 1px solid hsla(0, 0%, 100%, .4);
  display: grid;
  grid-template-columns: 1fr 15fr 15fr 0.1fr;
  margin-right: 50px;
  margin-left: 30px;
}

.addTask {
  margin-top: 20px;
  font-size: 30px;
  display: flex;
  justify-content: flex-end;
  margin-right: 50px;
  cursor: pointer;
}

.checkbox {
  width: 25px;
  height: 25px;
  border-radius: 50%;
  border: 1px solid hsla(0, 0%, 50%, .8);
  cursor: pointer;
}

.checked {
  background-color: #7af76e;
  background-position: 50% 50%;
  background-size: 15px;
  background-repeat: no-repeat;
}

.addToDo {
  font-size: 30px;
  margin-top: 12px;
  padding: 15px;
  border-radius: 5px;
  border: 1px solid hsla(0, 0%, 100%, .4);
  margin-right: 50px;
  margin-left: 30px;
  display: flex;
  gap: 20px;
}

#textInput {
  background-color: #444a4d;
  border: none;
  font-family: sans-serif;
  color: #fff;
  font-size: 18px;
  padding: 8px;
  border-radius: 5px;
  width: 100%;
}

#dateInput {
  background-color: #444a4d;
  border: none;
  font-family: sans-serif;
  color: #fff;
  font-size: 18px;
  padding: 8px;
  border-radius: 5px;
  width: 280px;
}

#submit {
  font-size: 16px;
  font-family: sans-serif;
  font-weight: bold;
  color: #fff;
  padding: 12px;
  border-radius: 5px;
  margin-top: 0;
  margin-bottom: 0;
  cursor: pointer;
  background-color: #00cd00;
  border: #00cd00;
  margin-left: 10px;
}

#cancel {
  font-size: 16px;
  font-family: sans-serif;
  font-weight: bold;
  color: #fff;
  padding: 12px;
  border-radius: 5px;
  margin-top: 0;
  margin-bottom: 0;
  cursor: pointer;
  background-color: red;
  border: red;
  margin-left: 12px;
}

.task-tem {
  font-size: 30px;
  margin-top: 12px;
  padding: 15px;
  border-radius: 5px;
  border: 1px solid hsla(0, 0%, 100%, .4);
  display: grid;
  grid-template-columns: 1fr 15fr 0.1fr;
  margin-right: 50px;
  margin-left: 30px;
}

.name {
  margin-left: 10px;
}
<div id="tasks">

  <div class="task">
    <div class="checkbox"></div>
    <div class="name"> task 1</div>
    <div class="date"></div>
    <div class="delete"><i>✖</i></div>
  </div>


  <div class="task">
    <input type="text" class="textInput" placeholder="Add Task">
    <input type="date" class="dateInput" placeholder="Add deadline">
    <button class="save">Submit</button>
    <button class="cancel">Cancel</button>
  </div>
  <div class="task">
    <input type="text" class="textInput" placeholder="Add Task">
    <input type="date" class="dateInput" placeholder="Add deadline">
    <button class="save">Submit</button>
    <button class="cancel">Cancel</button>
  </div>
</div>

0赞 user2226755 11/13/2023 #3

事件委派

您可以将事件侦听器添加到父元素而不是每个元素,如下所示:

const parentCheckbox = document.body
parentCheckbox.addEventListener('click', function (event) {
  const element = event.target
  if (element.classList.contains('checkbox')) { // is .checkbox
    element.classList.toggle('checked');
  }
})
.checked {
  box-shadow: 0 0 0 3px lightgreen;
}
<body>
  <p>checkbox class:</p>
  <input type="checkbox" class="checkbox" name="1" />
  <input type="checkbox" class="checkbox" name="1" />
  <input type="checkbox" class="checkbox" name="2" />
  <input type="checkbox" class="checkbox" name="2" />
  <p>not checkbox class:</p>
  <input type="checkbox" name="3" />
  <input type="checkbox" name="3" />
</body>

阅读更多: