首页 > 解决方案 > 为列表创建了删除功能,但并非所有选中的项目都在删除

问题描述

我目前正在参加 Wes Boros JS 30 挑战赛,对于这个特定的课程,我们创建了一个列表,在其中添加我们喜欢的食物。作为一项额外的任务,我们将创建一个selectall 函数、一个unselectall 函数和一个delete函数。我能够成功创建一个selectall 功能,一旦您单击该按钮,它就会选择当前列表中的所有项目。我的问题是我创建的删除功能会删除所有内容,除了一两个项目。那些未删除的项目仍处于选中状态,但我必须再次单击删除按钮才能将其删除。仅供参考:我的本地存储已包含在此练习中。

有人可以帮助我并解释我做错了什么吗?

这也是它的一个jsfiddle

这是我设置 HTML 的方式:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>LocalStorage</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="wrapper">
    <h2>LOCAL TAPAS</h2>
    <p></p>
    <ul class="plates">
      <li>Loading Tapas...</li>
    </ul>
    <form class="add-items">
      <input type="text" name="item" placeholder="Item Name" required>
      <input type="submit" value="+ Add Item">
    </form>
    <input type="button" onclick="selectAll()" value="Select All"/>
    <input type="button" onclick="UnSelectAll()" value="Unselect All"/>
    <input type="button" onclick="deleteItem()" value="delete Item"/>
  </div>
</body>
</html>

这是我的Javascript:

  const addItems = document.querySelector('.add-items');
  const itemsList = document.querySelector('.plates');
  const items = JSON.parse(localStorage.getItem('items')) || [];
  
  
  
  //DELETE FUNCTION
  function deleteItem(){
      var boxes = document.getElementsByClassName('chk');
      var texts = document.getElementsByClassName('txt');
      for(var i = 0; i < boxes.length; i++){
        box = boxes[i];
        txt = texts[i];
        if(box.checked){
          box.parentNode.removeChild(box);
          txt.parentNode.removeChild(txt);
        }
      }
       
  }


  //SELECT ALL FUNCTION
  function selectAll(){
    var checkedItem = document.getElementsByName('item');
      for (var i = 0; i < checkedItem.length; i++) {
        if (checkedItem[i].type == 'checkbox')
            checkedItem[i].checked = true;
      }
  }
  
  //UNSELECT ALL FUNCTION
  function UnSelectAll(){
    var checkedItem = document.getElementsByName('item');
      for (var i = 0; i < checkedItem.length; i++) {
        if (checkedItem[i].type == 'checkbox')
            checkedItem[i].checked = false;
      }
  }

  //ADD ITEM FUNCTIO
  function addItem(e){
    e.preventDefault()
    const text = (this.querySelector('[name=item]')).value;

    const item = {
      text,
      done: false
    };
    items.push(item); 
    populateList(items, itemsList);
    localStorage.setItem('items', JSON.stringify(items));
    this.reset();
  }
//DISPLAY THE HTML FUNCTION
function populateList(plates =[], platesList) {
  platesList.innerHTML = plates.map((plate, i) => {
    return `
      <li>
      <input class="chk" type="checkbox" name="item" data-index=${i} id="item${i}" ${plate.done ? 'checked' : ''} /> 
      <label class="txt" name="item" for="item${i}">${plate.text}</label>
      </li>
    `
}).join('');
}

function toggleDone(e){

 if(!e.target.matches('input')) return; 
 const el = e.target;
 const index = el.dataset.index;
 items[index].done = !items[index].done;
 localStorage.setItem('items', JSON.stringify(items));
 populateList(items, itemsList);
}
addItems.addEventListener('submit', addItem)
itemsList.addEventListener('click', toggleDone)
populateList(items, itemsList);


//DELETE ITEM EVENT HANDLER
itemsList.addEventListener('click', deleteItem);

标签: javascriptarrayslocal-storage

解决方案


您的删除功能无法正常工作的原因是Node.childNodes返回一个 liveNodeList这意味着当您removeChild在集合中的每个元素上使用时,其他元素会重新排列并且列表的长度会变小导致您跳过其中的一些元素所以您应该使用将您的 html 集合转换为数组Array.from

function deleteItem(){
var boxes = document.getElementsByClassName('chk');
var texts = document.getElementsByClassName('txt');
arrbox  = Array.from(boxes)
arrtext = Array.from(texts)
for(var i = 0; i < arrbox.length; i++){
var box = arrbox[i];
var txt = arrtext[i]; 
        if(box.checked){
          box.parentNode.removeChild(box);
          txt.parentNode.removeChild(txt);
        }
      }           
  }

这是工作的jsfiddle


推荐阅读