无法删除事件侦听器 Javascript
Unable to remove event listener Javascript
我试图在添加新事件处理程序之前删除事件处理程序。否则它会触发多次。这是调用 attach/remove 它的方法。
function attachRemoveBookEvent(bookEl) {
function remove() {
bookEl.remove();
for(let i=0; i < bookObjects.length; i++) {
if(bookObjects[i].id == bookEl.getAttribute("data-id")) {
bookObjects.splice(i, 1);
break;
}
}
hideContainer(removeContainer);
}
removeConfirm.removeEventListener("click", remove);
removeConfirm.addEventListener("click", remove);
}
我不确定是否因为方法实际上不相同,当我按下按钮时它会多次触发。
解释器每次遇到 function
关键字时,都会创建一个新函数。所以,如果你调用 attachRemoveBookEvent
并附加一个监听器,然后你再次调用 attachRemoveBookEvent
,你将不再有对 original remove
的引用在原始调用中创建的函数 - 相反,您有一个对刚刚创建的 new remove
函数的引用。不知何故,您必须确保传入的函数与调用 addEventListener
的函数相同。一种可能性是对附加到 removeConfirm
:
的当前 remove
进行持久引用
let remove = null;
function attachRemoveBookEvent(bookEl) {
removeConfirm.removeEventListener("click", remove);
remove = function remove() {
bookEl.remove();
for(let i=0; i < bookObjects.length; i++) {
if(bookObjects[i].id == bookEl.getAttribute("data-id")) {
bookObjects.splice(i, 1);
break;
}
}
hideContainer(removeContainer);
}
removeConfirm.addEventListener("click", remove);
}
或者,根据您想要的逻辑类型,您可以永久保持事件侦听器,而不是重新附加它,只重新分配 bookEl
,在持久化外部变量中,有点像:
let currentBookEl = null;
function remove() {
if (currentBookEl) currentBookEl.remove();
for(let i=0; i < bookObjects.length; i++) {
if(bookObjects[i].id == bookEl.getAttribute("data-id")) {
bookObjects.splice(i, 1);
break;
}
}
hideContainer(removeContainer);
}
function attachRemoveBookEvent(bookEl) {
currentBookEl = bookEl;
}
此外,当您试图在数组中查找元素的索引时,比手动迭代 bookObjects
和 break
ing 更好的选择是 findIndex
:
const idToFind = bookEl.getAttribute("data-id");
const index = bookObjects.find(({ id }) => id === idToFind);
bookObjects.splice(i, 1);
您可以向元素添加 class,并且仅在 class 不存在时才添加侦听器
function attachRemoveBookEvent(bookEl) {
function remove() {
bookEl.remove();
for (let i = 0; i < bookObjects.length; i++) {
if (bookObjects[i].id == bookEl.getAttribute("data-id")) {
bookObjects.splice(i, 1);
break;
}
}
hideContainer(removeContainer);
}
if(!removeConfirm.classList.contains('someClass')) {
removeConfirm.classList.add('someClass')
removeConfirm.addEventListener("click", remove);
}
}
我试图在添加新事件处理程序之前删除事件处理程序。否则它会触发多次。这是调用 attach/remove 它的方法。
function attachRemoveBookEvent(bookEl) {
function remove() {
bookEl.remove();
for(let i=0; i < bookObjects.length; i++) {
if(bookObjects[i].id == bookEl.getAttribute("data-id")) {
bookObjects.splice(i, 1);
break;
}
}
hideContainer(removeContainer);
}
removeConfirm.removeEventListener("click", remove);
removeConfirm.addEventListener("click", remove);
}
我不确定是否因为方法实际上不相同,当我按下按钮时它会多次触发。
解释器每次遇到 function
关键字时,都会创建一个新函数。所以,如果你调用 attachRemoveBookEvent
并附加一个监听器,然后你再次调用 attachRemoveBookEvent
,你将不再有对 original remove
的引用在原始调用中创建的函数 - 相反,您有一个对刚刚创建的 new remove
函数的引用。不知何故,您必须确保传入的函数与调用 addEventListener
的函数相同。一种可能性是对附加到 removeConfirm
:
remove
进行持久引用
let remove = null;
function attachRemoveBookEvent(bookEl) {
removeConfirm.removeEventListener("click", remove);
remove = function remove() {
bookEl.remove();
for(let i=0; i < bookObjects.length; i++) {
if(bookObjects[i].id == bookEl.getAttribute("data-id")) {
bookObjects.splice(i, 1);
break;
}
}
hideContainer(removeContainer);
}
removeConfirm.addEventListener("click", remove);
}
或者,根据您想要的逻辑类型,您可以永久保持事件侦听器,而不是重新附加它,只重新分配 bookEl
,在持久化外部变量中,有点像:
let currentBookEl = null;
function remove() {
if (currentBookEl) currentBookEl.remove();
for(let i=0; i < bookObjects.length; i++) {
if(bookObjects[i].id == bookEl.getAttribute("data-id")) {
bookObjects.splice(i, 1);
break;
}
}
hideContainer(removeContainer);
}
function attachRemoveBookEvent(bookEl) {
currentBookEl = bookEl;
}
此外,当您试图在数组中查找元素的索引时,比手动迭代 bookObjects
和 break
ing 更好的选择是 findIndex
:
const idToFind = bookEl.getAttribute("data-id");
const index = bookObjects.find(({ id }) => id === idToFind);
bookObjects.splice(i, 1);
您可以向元素添加 class,并且仅在 class 不存在时才添加侦听器
function attachRemoveBookEvent(bookEl) {
function remove() {
bookEl.remove();
for (let i = 0; i < bookObjects.length; i++) {
if (bookObjects[i].id == bookEl.getAttribute("data-id")) {
bookObjects.splice(i, 1);
break;
}
}
hideContainer(removeContainer);
}
if(!removeConfirm.classList.contains('someClass')) {
removeConfirm.classList.add('someClass')
removeConfirm.addEventListener("click", remove);
}
}