无法从待办事项列表中删除最后一项

时间:2019-04-26 01:36:46

标签: javascript

我做了一个简单的待办事项清单,到目前为止有2个功能。选中一个项目并从列表中删除一个项目。

如果我从列表的底部开始删除,我可以删除所有项目,但是当我从顶部删除时,第一个项目被删除,第二个项目(现在是第一个),在其后删除,然后不删除。当我点击X时会删除自己

我认为stopPropagration()会有所帮助,但似乎没有帮助。它只会停止其他已检查功能的运行。

<ul>
  <li><span>X</span> Code something</li>
  <li><span>X</span> Wake up early</li>
  <li><span>X</span> Buy popcorn</li>
</ul>
/**
 * This strikes through list item on click once and item is marked as done
 */
const listItem = document.getElementsByTagName('li')

for (let i = 0; i < listItem.length; i++) {
  listItem[i].addEventListener('click', () => {
    listItem[i].classList.toggle('checked')
  })
}

/**
 * This deletes an item from the list on click
 */
const deleteItem = document.getElementsByTagName('span')

for (let i = 0; i < deleteItem.length; i++) {
  deleteItem[i].addEventListener('click', e => {
    deleteItem[i].parentNode.remove()
    e.stopPropagation()
  })
}

https://jsfiddle.net/k2u8mqes/

预期结果是我应该能够以任意顺序删除每个项目

3 个答案:

答案 0 :(得分:1)

您的for循环将一些点击分配给您想要的不同元素。

此建议使用click事件的目标来确定需要实时删除的内容。 (具体来说,它将删除作为点击的li的父项的span。)

document.addEventListener("click", checkLi);
document.addEventListener("click", deleteSpanParent);

function checkLi(event){
  if(event.target.tagName == "LI"){
    event.target.classList.toggle("checked");
    event.target.style.color = "grey";
  }
}

function deleteSpanParent(event){
  if(event.target.tagName == "SPAN"){
    let span = event.target, li = span.parentNode, ul = li.parentNode;
    ul.removeChild(li);
  }
}
<ul>
  <li><span>X</span> Code something</li>
  <li><span>X</span> Wake up early</li>
  <li><span>X</span> Buy popcorn</li>
</ul>

答案 1 :(得分:0)

问题在于您使用循环绑定事件侦听器的方式以及您如何访问事件绑定到的特定元素。

而不是这样做;

listItem[i].classList.toggle('checked')
//and
deleteItem[i].parentNode.remove()

您可以使用事件侦听器的事件对象来访问绑定的元素,像这样;

e.target.classList.toggle('checked')
//and
e.target.parentNode.remove()

请在此处参考事件监听器API:https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

检查此小提琴以获取代码的有效示例:https://jsfiddle.net/491rLbxj/

答案 2 :(得分:0)

您要在迭代时修改数组,这是常见的警告。 从顶部删除时:

  
      
  1. 删除第一个项目,调用deleteItem[0].parentNode.remove(),删除deleteItem数组的第一个元素,没关系;
  2.   
  3. 删除第二个项目,调用deleteItem[1].parentNode.remove(),但是deleteItem现在的大小为2,实际上是在删除   原始数组的第三个元素;
  4.   
  5. 删除第三个项目,调用deleteItem[2].parentNode.remove(),但是deleteItem现在的大小为1,您的索引用完了;
  6.   

工作片段:

for (let i = 0; i < deleteItem.length; i++) {
  deleteItem[i].addEventListener('click', e => {
    e.target.parentNode.remove()
  })
}
相关问题