为什么我的待办事项列表复选框功能不适用于添加了 DOM 的元素?
Why isn't my todo list checkbox function applying to elements added with DOM?
正在使用 JavaScript 创建待办事项列表。我从我编码到 html 文件中的一些默认值 'to-dos' 开始。列表的结构是这样的
<h4 style="text-align: center;">Reminders To Do:</h4>
<p style="text-align: center;">Check off each task after completing it!</p>
<ul id="reminders" class="list-group">
<div id="task">
<li class="list-group-item" id="taskCheck"><input type="checkbox" name="task">Take out the trash</li>
</div>
<div id="task">
<li class="list-group-item" id="taskCheck"><input type="checkbox" name="task">Email boss about project</li>
</div>
<div id="task">
<li class="list-group-item" id="taskCheck"><input type="checkbox" name="task">Cancel subscriptions</li>
</div>
<div id="task">
<li class="list-group-item" id="taskCheck"><input type="checkbox" name="task">Go to gym</li>
</div>
</ul>
我可以通过在 'submit' 上使用 eventListener 等创建下面的表单来向此列表添加新事件。那里的一切都按预期工作。出现这个问题是因为我在 JS 中有一个函数应该设置 "style: display: "none";"
因此在完成后从列表中删除任务。这适用于默认事件。
let eventForm = document.querySelector('#taskForm');
let eventName = document.querySelector('input[name="newTask"]');
let eventDate = document.querySelector('input[name="taskDate"');
let reminders = document.querySelector('#reminders');
let msg = document.querySelector('.msg');
eventForm.addEventListener('submit', onSubmit);
function onSubmit(e) {
e.preventDefault();
if(eventName.value === '' || eventDate.value === '') {
msg.innerHTML = 'Please complete both fields.';
setTimeout(() => msg.remove(), 3000);
} else {
let div = document.createElement('div'); //structure is ul -> div -> li -> input
div.setAttribute('id', 'task');
let li = document.createElement('li');
li.setAttribute('id', 'taskCheck');
li.className += 'list-group-item'; //adds the bootstrap class to li
li.innerHTML += '<input type="checkbox" name="task">'; //since input tag is nested within li element
li.appendChild(document.createTextNode(`${eventName.value} | ${eventDate.value}`));
div.appendChild(li); //adds li to a div within the list
reminders.appendChild(div); //adds div into the list
//resets form fields to empty for another task
eventName.value = '';
eventDate.value = '';
}
}
即使我看到通过我的表单添加的新事件,当我选中/取消选中该框时也没有任何响应。
我删除选中事件的功能是这样的:注意我更改了功能,所以我没有不显示事件,而是使用 console.log();[=26= 进行测试]
let reminderList = document.querySelectorAll('#reminders li');
let tasksCheck = document.querySelectorAll('input[type="checkbox"]');
tasksCheck.forEach((task, i) => { //i holds the index of each task in the list
task.addEventListener('change', () => {
if(task.checked) {
console.log('Task completed!');
} else {
console.log('Task not completed yet.');
}
})
})
我知道 post 很长,非常感谢您的帮助。
如果我没有正确理解你的问题,我认为新任务没有响应点击事件,因为你在创建它们之前添加了事件监听。您可以使用 event delegation 通过类似于以下的代码来解决此问题:
let reminders = document.querySelector('#reminders'); // save the reminders
const handleTaskClick = e => {
if (e.target.tagName.toLowerCase() === 'input') {// check if it is a task element. You can use className here
const taskInput = e.target;
const task = taskInput.parentElement.parentElement; // get the task div
const taskIndex = Array.from(reminders.children).indexOf(task); // convert to an array look for its index
if(taskInput.checked) {
console.log('Task completed!', taskIndex);
} else {
console.log('Task not completed yet.', taskIndex);
}
}
}
// add the event listener to the reminders wrapper element #remiders
reminders.addEventListener('click', handleTaskClick);
正在使用 JavaScript 创建待办事项列表。我从我编码到 html 文件中的一些默认值 'to-dos' 开始。列表的结构是这样的
<h4 style="text-align: center;">Reminders To Do:</h4>
<p style="text-align: center;">Check off each task after completing it!</p>
<ul id="reminders" class="list-group">
<div id="task">
<li class="list-group-item" id="taskCheck"><input type="checkbox" name="task">Take out the trash</li>
</div>
<div id="task">
<li class="list-group-item" id="taskCheck"><input type="checkbox" name="task">Email boss about project</li>
</div>
<div id="task">
<li class="list-group-item" id="taskCheck"><input type="checkbox" name="task">Cancel subscriptions</li>
</div>
<div id="task">
<li class="list-group-item" id="taskCheck"><input type="checkbox" name="task">Go to gym</li>
</div>
</ul>
我可以通过在 'submit' 上使用 eventListener 等创建下面的表单来向此列表添加新事件。那里的一切都按预期工作。出现这个问题是因为我在 JS 中有一个函数应该设置 "style: display: "none";"
因此在完成后从列表中删除任务。这适用于默认事件。
let eventForm = document.querySelector('#taskForm');
let eventName = document.querySelector('input[name="newTask"]');
let eventDate = document.querySelector('input[name="taskDate"');
let reminders = document.querySelector('#reminders');
let msg = document.querySelector('.msg');
eventForm.addEventListener('submit', onSubmit);
function onSubmit(e) {
e.preventDefault();
if(eventName.value === '' || eventDate.value === '') {
msg.innerHTML = 'Please complete both fields.';
setTimeout(() => msg.remove(), 3000);
} else {
let div = document.createElement('div'); //structure is ul -> div -> li -> input
div.setAttribute('id', 'task');
let li = document.createElement('li');
li.setAttribute('id', 'taskCheck');
li.className += 'list-group-item'; //adds the bootstrap class to li
li.innerHTML += '<input type="checkbox" name="task">'; //since input tag is nested within li element
li.appendChild(document.createTextNode(`${eventName.value} | ${eventDate.value}`));
div.appendChild(li); //adds li to a div within the list
reminders.appendChild(div); //adds div into the list
//resets form fields to empty for another task
eventName.value = '';
eventDate.value = '';
}
}
即使我看到通过我的表单添加的新事件,当我选中/取消选中该框时也没有任何响应。
我删除选中事件的功能是这样的:注意我更改了功能,所以我没有不显示事件,而是使用 console.log();[=26= 进行测试]
let reminderList = document.querySelectorAll('#reminders li');
let tasksCheck = document.querySelectorAll('input[type="checkbox"]');
tasksCheck.forEach((task, i) => { //i holds the index of each task in the list
task.addEventListener('change', () => {
if(task.checked) {
console.log('Task completed!');
} else {
console.log('Task not completed yet.');
}
})
})
我知道 post 很长,非常感谢您的帮助。
如果我没有正确理解你的问题,我认为新任务没有响应点击事件,因为你在创建它们之前添加了事件监听。您可以使用 event delegation 通过类似于以下的代码来解决此问题:
let reminders = document.querySelector('#reminders'); // save the reminders
const handleTaskClick = e => {
if (e.target.tagName.toLowerCase() === 'input') {// check if it is a task element. You can use className here
const taskInput = e.target;
const task = taskInput.parentElement.parentElement; // get the task div
const taskIndex = Array.from(reminders.children).indexOf(task); // convert to an array look for its index
if(taskInput.checked) {
console.log('Task completed!', taskIndex);
} else {
console.log('Task not completed yet.', taskIndex);
}
}
}
// add the event listener to the reminders wrapper element #remiders
reminders.addEventListener('click', handleTaskClick);