如何复制使用事件侦听器DOM节点?(How to copy a DOM node with even

2019-07-21 14:46发布

我试过了

node.cloneNode(true); // deep copy

它似乎并没有复制我添加使用事件侦听器node.addEventListener("click", someFunc);

我们使用Dojo库。

Answer 1:

cloneNode()不会复制事件侦听器。 事实上,没有通过一旦被附着在DOM越来越事件侦听器的保持的方式,让你的选择是:

  • 所有手动事件侦听器添加到您的克隆节点
  • 重构代码中使用事件代表团,以便所有的事件处理程序连接到包含原始和克隆节点
  • 各地使用的包装功能Node.addEventListener()来跟踪监听器添加到每个节点。 这是jQuery的如何clone()方法能够节点复制其事件监听器,例如。


Answer 2:

事件代表团例子。

阅读蒂姆向下的回答后,我发现委派事件是很容易实现,解决了类似的问题,我有。 我以为我想补充一个具体的例子,虽然它在JQuery中没有道场。

我重新skining语义UI,这需要一小块JS,使消息关闭按钮工作的应用程序。 然而,消息是从使用HTML模板标记克隆document.importNode在库中。 这甚至意味着如果我没有附加的事件处理程序的模板在新的HTML,它们在克隆过程中丢失。

我不能做添的选项1,克隆的过程中简单地重新连接它们的消息库前端框架无关。 (有趣的是我以前的前端是Zurb基金会其使用“数据闭合的”属性,该功能,其中不存活克隆过程)。

在正常的事件处理建议是这样的 :

$('.message .close').on('click', function() {
    $(this)
    .closest('.message')
    .transition('fade');
});

在应用负载的问题是“.message”只匹配了一个模板,而不是其在网络插座后到达的实际消息。

使这一委托,意味着该事件附接到到其中的消息被克隆的容器<div id="user-messages">

因此,它变成了:

$('#user-messages').on('click', '.message .close', function() {
    $(this)
    .closest('.message')
    .transition('fade');
});

这立即工作,节约包装一样的事件潜艇的第三个选项任何复杂的工作。

该道场相当于看起来在概念上非常相似。



Answer 3:

这不回答这个问题完全是,但如果用例允许用于移动元素,而不是复制它,你可以使用removeChild之一起使用appendChild将保留事件侦听器。 例如:

function relocateElementBySelector(elementSelector, destSelector) {
  let element = document.querySelector(elementSelector);
  let elementParent = element.parentElement;
  let destElement = document.querySelector(destSelector);
  elementParent.removeChild(element);
  destElement.appendChild(element);
}


文章来源: How to copy a DOM node with event listeners?