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

问题描述 投票:0回答:2

我用JS编写了一个非常简单的Todo应用程序。它工作正常,我有一些默认任务,我可以点击它们来改变它们完成或撤消,但问题是当我添加一个新任务时,我无法对它做任何事情。

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')
    }

  })
})

这是我在Codepen上的PEN

javascript foreach
2个回答
1
投票

li.addEventListener('click', e => {
  if ( e.target.classList.contains('done') ) {
    e.target.classList.remove('done')
  } else {
    e.target.classList.add('done')
  }
});

li.appendChild(text);

在将节点插入DOM之前,在节点上添加单击侦听器。

分叉和固定片段:

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>

0
投票

您可以通过将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>
© www.soinside.com 2019 - 2024. All rights reserved.