javascript - 从 querySelectorAll 更改为 getElementsByClassName 后,按钮未按预期删除元素

标签 javascript html css

在我开始使用 let getListObjects = document.getElementsByClassName("todoListItems") 而不是 let getListObjects = document. querySelectorAll('li')

这样做的原因是因为我在应用程序中的页面的单独部分添加了另一个 UL 部分,并希望这些列表项执行其他操作。

长话短说,我只能删除主应用程序中 2/3 的列表项,除非我先删除底部的 li 项,然后让我删除所有这些项。这对我来说毫无意义。下面是代码。

function applyButton() { //onload for dummy data or data from db
  let getListObjects = document.getElementsByClassName("todoListItems")

  for (let i = 0; i < getListObjects.length; i++) {

    let node2 = document.createElement('a')
    let iconNode = document.createElement('i')
    let att = document.createAttribute("href");
    att.value = "#"
    node2.setAttributeNode(att)
    node2.appendChild(iconNode)
    iconNode.classList.add('far')
    iconNode.classList.add('fa-trash-alt')
    iconNode.classList.add('trashCan')


    getListObjects[i].appendChild(node2)
    //addEventToButton2(getListObjects[i]) no need for it, keeping it here as a reminder of what happens with scoping

    node2.addEventListener('click', function() {
      node2.parentNode.parentNode.removeChild(getListObjects[i])
    });

  }

}
<div>
  <ul id='list-body'>
    <li id='enterItem'><input type='text' placeholder="Enter List Item..." id='newNote' class='inputEnterItem'></li>
    <li class='todoListItems'><span>Walk Dog Hit Gym and Lift Bro Hit Gym and Lift Bro  Hit Gym and Lift Bro Hit Gym and Lift Bro</span></li>
    <li class='todoListItems'><span>Hit Gym and Lift Bro</span></li>
    <li class='todoListItems'><span>Stretch</span></li>
  </ul>
</div>

TLDR:在我使用 querySelectorAll 选择这些 LI 元素之前,它没有任何错误。现在我按 className 选择它们,如果我先删除底部的 LI,它就会出错,只允许我删除 li 元素的 2/3 或所有 3 个元素

最佳答案

getElementsByClassName 返回一个事件 集合。如果将集合保存在一个变量中,然后从 DOM 中删除集合中的一个元素,或者将另一个具有相同类名的元素添加到 DOM 中,集合将发生变化:

const foos = document.getElementsByClassName('foo');
console.log(foos.length);
foos[0].remove();
console.log(foos.length);
<div class="foo"></div>

这很不直观,因为如果您正在做任何可以更改集合的事情,它可能会自行发生变异。 querySelectorAll 返回一个 static NodeList,它不是事件的 - 例如,索引 3 处的元素将永远从索引 3 处删除,即使从 DOM 中删除,除非您明确进入并将其从 NodeList 中删除。

简单的解决方案:改用querySelectorAll

要使用 querySelectorAll 选择特定类名的所有元素,请将 . 放在类名前面:更改

document.getElementsByClassName('foo');

document.querySelectorAll('.foo');

另一种可能性是在循环的每次迭代中保存对当前 getListObjects[i] 的引用:

let getListObjects = document.getElementsByClassName("todoListItems")
for(let i = 0; i< getListObjects.length; i++){
  const listObject = getListObjects[i];
  // now that we have a reference to the singular element,
  // don't ever refer to the collection again:

  let node2 = document.createElement('a')
  // ...


  listObject.appendChild(node2)

  node2.addEventListener('click', function(){
    node2.parentNode.parentNode.removeChild(listObject)  
  });
}

如果需要,您还可以使用 listObject.remove() 稍微清理一下点击监听器:

node2.addEventListener('click', function(){
  listObject.remove();
});

关于javascript - 从 querySelectorAll 更改为 getElementsByClassName 后,按钮未按预期删除元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55273335/

相关文章:

javascript - Bootstrap-table 过滤器扩展使用 html 选项的完整列表填充 <select>

javascript - 无法确定数据的编码方式

javascript - 动态变化的列表构造

javascript - 如何使用 knockout.js 设置数据绑定(bind)到 SVG 图像?

javascript - 有重复选项时如何检测数据列表中的选定选项?

css - 如何让不同长度的网格元素包裹起来?

javascript - 如何在 AngularJS 中优雅地动态加载特定的本地化文件?

javascript - 重新添加谷歌地图标记

css - 无法使用 .css 文件为 JSF 页面加载资源(图标)

css - li 文本下方的 ol 数字