我已经创建了一个简单的演示(https://codepen.io/anon/pen/VgKQoq),其中包含单击按钮时要创建的元素和对象:它创建一个元素,然后将该元素的对象放入'objects '数组。单击删除按钮时,将使用ID成功删除元素和对象。
但是,问题在于,每次删除某个元素时,根据单击哪个元素,删除功能有时会运行太多次,我不知道为什么。在演示中,打开javascript控制台,创建例如4个元素,然后通过单击remove删除第三个元素,然后您会看到会发生什么。
有谁知道为什么会这样吗?我认为这可能是因为事件侦听器一次又一次地添加到了相同的元素,但是删除后似乎无法正常工作。谢谢您的任何解释和最佳做法。
var id = 0, objects = [], removes;
function createEntry() {
id++;
// create new element, append to #container & create new object
var container = document.querySelector('#container'),
newEntry = document.createElement("div"),
title = 'title text here',
description = 'description text here',
remove = 'remove',
dataId = id,
obj = new Entry(title, description, remove);
newEntry.classList.add("entry");
newEntry.innerHTML = '<span class="title">' + title + '</span><span class="description">' + description + '</span><span class="remove">' + remove + '</span>';
container.appendChild(newEntry);
newEntry.setAttribute('data-id', id);
updateElements();
// constructor & push into array
function Entry(title, description, remove) {
this.title = title;
this.description = description;
this.remove = remove;
this.id = id;
objects.push(this);
}
// tests
console.log('JSON.stringify(obj): ' + JSON.stringify(obj));
console.log('obj.id: ' + obj.id);
function updateElements() {
removes = document.querySelectorAll(".remove");
listenForRemoves();
function listenForRemoves() {
for (let remove of removes) {
remove.removeEventListener("click", removeElements);
remove.addEventListener("click", removeElements);
}
}
function removeElements() {
let removedId = this.parentNode.getAttribute('data-id'),
objToRemove = objects.find(obj => obj.id == removedId); // not used
this.parentNode.remove(); console.log('removed id ' + removedId);
console.log('objects before: '); for (let object of objects) { console.log(JSON.stringify(object))};
objects = objects.filter(obj => obj.id != removedId); // doesn't use objToRemove
console.log('objects now: '); for (let object of objects) { console.log(JSON.stringify(object))};
}
}
// works but why the repeating console logs twice?
}
button { display: block }
.entry {
width: 100%;
display: block;
padding: 10px;
border: 1px solid #f5f5f5;
}
span {
display: block;
width: 100%;
}
section { background: lightgreen }
<button id='btn' onclick='createEntry()'>Create</button>
<section id='container'></section>
更新:还有其他想法吗?我已经添加了remove.removeEventListener("click", removeElements);
它,现在它消除了很多重复,但是现在它仍然仅控制台日志两次(嗯...有时候!!)。上面更新了新的Codepen链接
我不确定到底发生了什么,但是您将所有这些函数嵌套在createEntry函数内部。尝试将它们移出该功能。这似乎解决了我测试中的问题:
var id = 0, objects = [], removes;
function createEntry() {
id++;
// create new element, append to #container & create new object
var container = document.querySelector('#container'),
newEntry = document.createElement("div"),
title = 'title text here',
description = 'description text here',
remove = 'remove',
dataId = id,
obj = new Entry(title, description, remove);
newEntry.classList.add("entry");
newEntry.innerHTML = '<span class="title">' + title + '</span><span class="description">' + description + '</span><span class="remove">' + remove + '</span>';
container.appendChild(newEntry);
newEntry.setAttribute('data-id', id);
updateElements();
// constructor & push into array
function Entry(title, description, remove) {
this.title = title;
this.description = description;
this.remove = remove;
this.id = id;
objects.push(this);
}
// tests
console.log('JSON.stringify(obj): ' + JSON.stringify(obj));
console.log('obj.id: ' + obj.id);
}
function updateElements() {
removes = document.querySelectorAll(".remove");
listenForRemoves();
function listenForRemoves() {
for (let remove of removes) {
remove.removeEventListener("click", removeElements);
remove.addEventListener("click", removeElements);
}
}
}
function removeElements(e) {
let removedId = this.parentNode.getAttribute('data-id'),
objToRemove = objects.find(obj => obj.id == removedId); // not used
this.parentNode.remove(); console.log('removed id ' + removedId);
console.log('objects before: '); for (let object of objects) { console.log(JSON.stringify(object) + " " + e.target)};
objects = objects.filter(obj => obj.id != removedId); // doesn't use objToRemove
console.log('objects now: '); for (let object of objects) { console.log(JSON.stringify(object))};
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句