I write a very simple Todo app with JS . It's work fine, I have some default tasks that I can click on them to change them to done or undone, but the problem is when I add a new task, I can't do anything on it.
const input = document.querySelector('#todoText');
const todo = document.querySelector('#todo');
const todoLi = document.querySelectorAll('#todo li');
// Add Todo
input.addEventListener('keyup', e => {
if (e.keyCode === 13) {
// Get input value
let val = e.target.value;
// Create <li>
const li = document.createElement('li');
// Create text node from input value
let text = document.createTextNode(val);
// Pass input value into <li>
li.appendChild(text);
// Add input value in Todo list
todo.appendChild(li);
// Reset input value after enter
e.target.value = '';
}
})
todoLi.forEach( item => {
item.addEventListener('click', e => {
if ( e.target.classList.contains('done') ) {
e.target.classList.remove('done')
} else {
e.target.classList.add('done')
}
})
})
This is my PEN on Codepen
Add
li.addEventListener('click', e => {
if ( e.target.classList.contains('done') ) {
e.target.classList.remove('done')
} else {
e.target.classList.add('done')
}
});
After
li.appendChild(text);
To add a click listener on the node before you insert it into the DOM.
Forked and fixed snippet:
const input = document.querySelector('#todoText'); const todo = document.querySelector('#todo'); const todoLi = document.querySelectorAll('#todo li'); // Add Todo input.addEventListener('keyup', e => { if (e.keyCode === 13) { // Get input value let val = e.target.value; // Create <li> const li = document.createElement('li'); // Create text node from input value let text = document.createTextNode(val); // Pass input value into <li> li.appendChild(text); li.addEventListener('click', e => { if ( e.target.classList.contains('done') ) { e.target.classList.remove('done') } else { e.target.classList.add('done') } }); // Add input value in Todo list todo.appendChild(li); // Reset input value after enter e.target.value = ''; } }) todoLi.forEach( item => { item.addEventListener('click', e => { if ( e.target.classList.contains('done') ) { e.target.classList.remove('done') } else { e.target.classList.add('done') } }) })
body { margin: 50px; } input { padding: 5px 15px; background: #eee; border: 0; width: 100%; margin-left: 10px; border: solid 2px #eee; border-radius: 50px; transition: all 350ms; font-size: 12px; &:focus { border: solid 2px #eee; background: #fff; outline: none; } } ul { li { position: relative; cursor: pointer; transition: all 350ms; &:hover { &:before { content: '👉'; position: absolute; left: -25px } } } } .done { text-decoration: line-through; color: #888; }
<div class="d-flex align-items-center mb-5"> <span class="font-weight-bold text-muted">TODO:</span> <input id="todoText" placeholder="Write something and press Enter"> </div> <small>Todo list:</small> <ul id="todo"> <li>Add something new 👽</li> <li>This is a todo app with JS 🦄</li> <li class="done">I'm a done task 👁😍</li> </ul> <hr>
You might solve your problem and simplify your code by adding click
event listener to #todo
, not to li
elements:
const input = document.querySelector('#todoText'); const todo = document.querySelector('#todo'); // Add Todo input.addEventListener('keyup', e => { if (e.keyCode === 13) { // Get input value let val = e.target.value; // Create <li> const li = document.createElement('li'); // Create text node from input value let text = document.createTextNode(val); // Pass input value into <li> li.appendChild(text); // Add input value in Todo list todo.appendChild(li); // Reset input value after enter e.target.value = ''; } }) todo.addEventListener('click', e => { var li = e.target; while (li.nodeName.toLowerCase() !== 'li') { if (li === this) return; li = li.parentNode; } li.classList.toggle('done') })
body { margin: 50px; } input { padding: 5px 15px; background: #eee; border: 0; width: 100%; margin-left: 10px; border: solid 2px #eee; border-radius: 50px; transition: all 350ms; font-size: 12px; &:focus { border: solid 2px #eee; background: #fff; outline: none; } } ul { li { position: relative; cursor: pointer; transition: all 350ms; &:hover { &:before { content: '👉'; position: absolute; left: -25px } } } } .done { text-decoration: line-through; color: #888; }
<div class="d-flex align-items-center mb-5"> <span class="font-weight-bold text-muted">TODO:</span> <input id="todoText" placeholder="Write something and press Enter"> </div> <small>Todo list:</small> <ul id="todo"> <li>Add something new 👽</li> <li>This is a todo app with JS 🦄</li> <li class="done">I'm a done task 👁😍</li> </ul> <hr>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.