javascript - 为列表创建了删除功能,但并非所有选中的项目都在删除
问题描述
我目前正在参加 Wes Boros JS 30 挑战赛,对于这个特定的课程,我们创建了一个列表,在其中添加我们喜欢的食物。作为一项额外的任务,我们将创建一个select
all 函数、一个unselect
all 函数和一个delete
函数。我能够成功创建一个select
all 功能,一旦您单击该按钮,它就会选择当前列表中的所有项目。我的问题是我创建的删除功能会删除所有内容,除了一两个项目。那些未删除的项目仍处于选中状态,但我必须再次单击删除按钮才能将其删除。仅供参考:我的本地存储已包含在此练习中。
有人可以帮助我并解释我做错了什么吗?
这也是它的一个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);
解决方案
您的删除功能无法正常工作的原因是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
推荐阅读
- git - 使用 Colab 提交到 Github 并得到:错误:pathspec 'commit'' did not match any file(s) known to git
- django - 使用 Django 的 github 操作上的迁移错误
- android - 每次变量更改时,如何从活动 B 更新活动 A 中的变量?
- c - 任务是使用 p 线程并行化矩阵乘法并使用英特尔 ISPC 编译器进行矢量化
- node.js - 无法将文件发送到 express/multer 后端
- angular - 将 http 响应映射到 typeScript 对象
- r - 将文本标签添加到 geom_smooth 平均线
- emacs - 移除 Emacs 小地图中的边缘箭头
- firebase - 如何使用云功能授权触发颤振/飞镖
- jquery - 使用 jquery 获取 3rd 方控件的 innerHTML 中存在的特定元素的值