简体   繁体   English

forEach 无法读取新的节点元素 - js

[英]forEach can't read new node elements - js

I write a very simple Todo app with JS .我用JS编写了一个非常简单的Todo 应用程序 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这是我在 Codepen 上的PEN

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.在将节点插入 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:您可以通过将click事件侦听器添加到#todo而不是li元素来解决您的问题并简化您的代码:

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM