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

Javascript 如何使用事件侦听器复制DOM节点?,javascript,dom,dojo,Javascript,Dom,Dojo,我试过了 它似乎没有复制我使用node.addEventListener(“单击”,someFunc)添加的事件侦听器 我们使用Dojo库。cloneNode()不复制事件侦听器。事实上,一旦事件侦听器被连接,就无法通过DOM获得它们,因此您可以选择: 将所有事件侦听器手动添加到克隆节点 重构代码以使用事件委派,以便将所有事件处理程序附加到包含原始和克隆的节点 在节点周围使用包装函数。addEventListener()跟踪添加到每个节点的侦听器。例如,jQuery的方法就是这样使用事件侦听器

我试过了

它似乎没有复制我使用
node.addEventListener(“单击”,someFunc)添加的事件侦听器

我们使用Dojo库。

cloneNode()
不复制事件侦听器。事实上,一旦事件侦听器被连接,就无法通过DOM获得它们,因此您可以选择:

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

事件委派示例。

阅读Tim Down的答案后,我发现委派事件非常容易实现,解决了我遇到的类似问题。我想我会添加一个具体的示例,尽管它是在JQuery中而不是在Dojo中

我正在语义UI中重新封装一个应用程序,这需要一小段JS才能使消息关闭按钮正常工作。但是,这些消息是使用库中的
document.importNode
从HTML模板标记克隆的。这意味着,即使我将事件处理程序附加到新HTML中的模板,它们也会在克隆过程中丢失

我不能执行Tim的选项1,即在克隆过程中简单地重新连接它们,因为消息传递库与前端框架无关。(有趣的是,我以前的前端是ZURB基金会,它使用了一个“数据可关闭”的属性,它的功能在克隆过程中幸存下来。” 委员会:

问题是,应用程序加载时的“.message”仅与单个模板匹配,而与稍后通过web套接字到达的实际消息不匹配

进行此委派意味着将事件附加到消息克隆到的容器中

因此,它变成:

$('.message .close').on('click', function() {
    $(this)
    .closest('.message')
    .transition('fade');
});
这立即起作用,节省了任何复杂的工作,如包装事件子对象的第三个选项


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

这并不能准确回答问题,但如果用例允许移动元素而不是复制元素,则可以与一起使用,这样可以保留事件侦听器。例如:

$('#user-messages').on('click', '.message .close', function() {
    $(this)
    .closest('.message')
    .transition('fade');
});
这就是我们在评论中所描述的。使用此HTML代码创建初始元素

触摸我

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


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

当坏习惯(如
onclick
之类的内联javascript)比普通的替代方法更方便时,您难道不讨厌它吗?唉……人们通常使用不好的做法,因为它们更方便,但这并不能使它们变得好。您是否有一个代码示例,说明如何将事件侦听器添加到克隆的代码中?@RoelofCoertze-您必须知道哪些事件侦听器是首先添加的,并且在执行克隆的代码中也有访问权限,要再次分配回调,因为根据代码中克隆发生的位置,访问回调可能很棘手,因此示例将毫无用处,因为场景太多。当前面临此问题。当我们谈论事件监听器复制时,cloneNode的行为似乎相当棘手:
它不复制使用addEventListener()添加的事件监听器或分配给元素属性(例如node.onclick=fn)的事件监听器。
这也称为内容属性,它独立于。
$('#user-messages').on('click', '.message .close', function() {
    $(this)
    .closest('.message')
    .transition('fade');
});
function relocateElementBySelector(elementSelector, destSelector) {
  let element = document.querySelector(elementSelector);
  let elementParent = element.parentElement;
  let destElement = document.querySelector(destSelector);
  elementParent.removeChild(element);
  destElement.appendChild(element);
}