如何使用事件侦听器复制DOM节点?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用事件侦听器复制DOM节点?相关的知识,希望对你有一定的参考价值。

我试过了

node.cloneNode(true); // deep copy

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

我们使用Dojo库。

答案

cloneNode()不复制事件监听器。实际上,一旦附加了DOM,就无法通过DOM获取事件监听器,因此您的选择是:

  • 手动将所有事件侦听器添加到克隆节点
  • 重构您的代码以使用事件委派,以便所有事件处理程序都附加到包含原始和克隆的节点
  • 使用Node.addEventListener()周围的包装函数来跟踪添加到每个节点的侦听器。例如,这就是jQuery的clone()方法能够使用其事件侦听器复制节点的方式。
另一答案

事件委派示例。

阅读Tim Down的回答后,我发现委派的事件很容易实现,解决了我遇到的类似问题。我想我会添加一个具体的例子,虽然它是在JQuery而不是Dojo。

我在Semantic UI中重新创建了一个应用程序,它需要一小段JS来使消息关闭按钮工作。但是,使用库中的document.importNodehtml模板标记克隆消息。这意味着即使我将事件处理程序附加到新HTML中的模板,它们也会在克隆过程中丢失。

我无法做Tim的选项1,只是在克隆过程中重新附加它们,因为消息传递库与前端框架无关。 (有趣的是,我之前的前端是在Zurb Foundation,它使用了一个“数据可关闭”属性,其功能在克隆过程中幸存下来)。

normal event handling suggested was like this

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

app-load中的“.message”问题只与单个模板匹配,而不是以后通过Web套接字到达的实际消息。

使这个委托,意味着将事件附加到消息克隆的容器<div id="user-messages">

所以它变成:

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

这立即起作用,保存了任何复杂的工作,比如包装事件子的第三个选项。

Dojo equivalent在概念上看起来非常相似。

另一答案

这并不完全回答这个问题,但是如果用例允许移动元素而不是复制它,你可以使用removeChildappendChild来保存事件监听器。例如:

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

这就是@JeromeJ在评论中描述的内容。使用此HTML代码创建初始元素。

<DIV ONCLICK="doSomething(this)">touch me</DIV>

克隆此元素时,结果将具有相同的处理程序,“this”将指向克隆元素。

如果可以在javascript中轻松添加ONCLICK处理程序,那就太好了。这种方法意味着您必须用HTML编写一些代码。

以上是关于如何使用事件侦听器复制DOM节点?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用事件侦听器来加载动画片段的循环

JS中的事件传播流程

如何为附加到元素的每个事件侦听器打印或迭代? [复制]

js事件流事件处理程序/事件侦听器

DOM操作 ——如何添加移除移动复制创建和查找节点等。

js如何清除dom节点上的指定监听事件?