我需要从数组中删除对象的帮助。
对象中的名称(array.name)显示在DOM中,我想使用“擦除X”按钮将其删除。
在此代码中,我只能删除一个元素,然后在没有控制台错误的情况下停止工作。 有谁知道我错了,为什么我每次单击擦除按钮时都不能调用create()函数。
看console.log ...它显示了要删除的元素的良好位置和名称,但是当我调用create()函数并取消注释create()时,一切都停止了。
const array = [ {name: 'John'}, {name: 'David'}, {name: 'Peter'}, {name: 'Michael'} ];
const create = () => {
const app = document.querySelector('.app');
app.innerHTML = '';
for(let i = 0; i < array.length; i++) {
app.innerHTML += `<div class="item"><span class="erase">☓</span>${array[i].name}</div>`;
}
}
create();
const erase = document.querySelectorAll('.erase');
erase.forEach(item => {
item.onclick = () => {
const itemText = item.parentElement.textContent.substr(1);
const itemPos = array.findIndex(item => item.name == itemText);
console.log(itemText + ' ' + itemPos);
console.log(array);
array.splice(itemPos, 1);
//create()
}
});
.erase {
color: red;
margin-right: 20px;
cursor: pointer;
}
.item {
margin-bottom: 10px;
}
<div class="app"></div>
或者作为小提琴:https://jsfiddle.net/05cwy9d2/3/
答案 0 :(得分:3)
这是因为在dom中创建新元素时,旧元素的侦听器会与旧元素一起被删除。只需将事件侦听器注册移到create方法中即可。
const array = [
{name: 'John'},
{name: 'David'},
{name: 'Peter'},
{name: 'Michael'}
];
const create = () => {
const app = document.querySelector('.app');
app.innerHTML = '';
for(let i=0;i<array.length;i++){
app.innerHTML +=
`<div class="item"><span class="erase">☓</span>${array[i].name}</div>`;
}
const erase = document.querySelectorAll('.erase');
erase.forEach(item => {
item.onclick = () => {
const itemText = item.parentElement.textContent.substr(1);
const itemPos = array.findIndex(item => item.name == itemText);
console.log(itemText + ' ' + itemPos);
console.log(array);
array.splice(itemPos, 1);
create();
}
});
}
create();
.erase{
color: red;
margin-right: 20px;
cursor: pointer;
}
.item{
margin-bottom: 10px;
}
<div class="app"></div>
答案 1 :(得分:1)
const array = [
{name: 'John'},
{name: 'David'},
{name: 'Peter'},
{name: 'Michael'}
];
const create = () => {
const app = document.querySelector('.app');
app.innerHTML = '';
for(let i=0;i<array.length;i++){
app.innerHTML +=
`<div class="item"><span class="erase">☓</span>${array[i].name}</div>`;
}
}
create();
const erase = document.querySelectorAll('.erase');
erase.forEach(item => {
item.onclick = () => {
const itemText = item.parentElement.textContent.substr(1);
const itemPos = array.findIndex(item => item.name == itemText);
console.log(itemText + ' ' + itemPos);
if(itemPos >-1){
array.splice(itemPos, 1);
item.parentElement.remove();
}
console.log(array);
}
});
现在可以使用。单击删除时已删除DOM,并禁止用户删除已删除的元素(如果index == -1)。
答案 2 :(得分:0)
答案 3 :(得分:0)
我将事件侦听器代码移至create函数,因为需要在一个事件发生时重新创建。您还可以使用EventTarget.addEventListener()方法将事件侦听器绑定到每个单个DOM元素。
我也更愿意使用Array.prototype.filter()方法删除点击的值,以提高可读性:
let array = [
{name: 'John'},
{name: 'David'},
{name: 'Peter'},
{name: 'Michael'}
];
const addEventListeners = () => {
const erase = document.querySelectorAll('.erase');
erase.forEach(item => {
item.onclick = (e) => {
const itemText = item.parentElement.textContent.substr(1);
array = array.filter(entry => entry.name !== itemText);
create();
}
});
}
const create = () => {
const app = document.querySelector('.app');
app.innerHTML = '';
for(let i=0;i<array.length;i++){
app.innerHTML +=
`<div class="item"><span class="erase">☓</span>${array[i].name}</div>`;
}
addEventListeners();
}
create();
<div class="app"></div>
答案 4 :(得分:0)
您可以使用方法removeChild
从DOM中删除元素,这样可以防止每次从数组中删除项目时都重新渲染(使用 create 方法) 。这样,您的代码将需要进行一些更改,第一个更改是为数组的每个元素都有一个ID:
for(let person of array){
app.innerHTML +=
`<div class="item" id="${person.name}"><span class="erase">☓</span>${person.name}</div>`;
}
将“人员”名称作为ID(我建议您使用一个真实的标识符,例如数字,但在此示例中,名称将对我们有帮助),您只能将该节点从DOM中删除:
const elementToRemove = document.getElementById(item.parentElement.id);
elementToRemove.parentNode.removeChild(elementToRemove);
要增强功能,您可以检查节点是否存在,如果不存在,则可以向控制台抛出错误:
const elementToRemove = document.getElementById(item.parentElement.id);
if (!elementToRemove) throw new Error(`Element ${item.parentElement.id} not found!`)
elementToRemove.parentNode.removeChild(elementToRemove)
我建议您阅读Node section on MDN,这对于将其他元素添加到列表,编辑某些元素等等很有用。 :)
答案 5 :(得分:0)
您将使用item.parentElement.remove()来代替再次调用create()函数并为类'.app'创建新的子元素;代替onClick中的create()。那会得到相同的结果。
erase.forEach(item => {
item.onclick = () => {
console.log()
const itemText = item.parentElement.textContent.substr(1);
const itemPos = array.findIndex(item => item.name == itemText);
console.log(itemText + ' ' + itemPos);
console.log(array);
array.splice(itemPos, 1);
item.parentElement.remove(); // this will remove your element.
// create();
}
});