cloneNode 不会丢失事件监听器

Posted

技术标签:

【中文标题】cloneNode 不会丢失事件监听器【英文标题】:cloneNode without losing event listener 【发布时间】:2021-12-27 10:26:46 【问题描述】:

如何在不丢失附加到按钮的事件侦听器的情况下移动我的 html 元素?

克隆和移除原始元素后,子按钮的事件监听器不起作用

ul.appendChild(element.cloneNode(true));
element.remove();

【问题讨论】:

使用event delegation —— 它更易于维护,适用于动态添加的元素。例如,使用event argument 的target。请参阅 the tag info 和 What is DOM Event delegation?。假设ul<ul>,则执行addEventListener("click", ( target ) => const li = target.closest("li"); if(li) ); 【参考方案1】:

你说过你想移动它,但你正在做的是克隆它,保存克隆,然后删除并丢弃原件。相反,不要克隆它,移动它:

ul.appendChild(element);

这将从其当前父级中删除 element 并将其放入其新父级 (ul) 中,而所有事件侦听器仍然存在。

现场示例:

// NOTE: This isn't how I'd write this code if I weren't demonstrating
// the fact the listeners are retained when the element is moved.
// But without context, it's hard to show a delegation solution.

const list1 = document.getElementById("list1");
const list2 = document.getElementById("list2");

// Add a listeneer to each `li`
document.querySelectorAll("li").forEach((li, index) => 
    li.addEventListener("click", () => 
        console.log(`Moving "$li.textContent" which was originally at index $index`);
        if (li.closest("ul") === list1) 
            // Move from list1 to list2
            list2.appendChild(li);
         else 
            // Move from list2 to list1
            list1.appendChild(li);
        
    );
);
li 
    cursor: pointer;
<div>List 1:</div>
<ul id="list1">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ul>
<div>List 2:</div>
<ul id="list2">
    <li>Item 4</li>
    <li>Item 5</li>
    <li>Item 6</li>
</ul>
<div>Click an item to move it to the other list.</div>

也就是说,我经常发现事件委托在处理在父级之间移动的元素时是最好的,但这确实取决于具体情况。

【讨论】:

以上是关于cloneNode 不会丢失事件监听器的主要内容,如果未能解决你的问题,请参考以下文章

Zookeeper之Watcher监听事件丢失分析

JAVA 求助 就是如何用鼠标监听事件调用Graphics 画的线条和矩形 接着画 ? 不会画完

如何在Angular项目里监听页面关闭、跳转事件?

事件监听器

addEventListener 事件监听器 冒泡事件)

javascript事件监听