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

Cha*_*aju 52 javascript dojo dom

我试过了

node.cloneNode(true); // deep copy
Run Code Online (Sandbox Code Playgroud)

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

我们使用Dojo库.

Tim*_*own 66

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

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

  • 当不良习惯(像onclick`这样的内联javascript)比适当的香草替代品更方便时,你不讨厌它吗?叹... (14认同)
  • @jeromej,这并不总是一个坏习惯:在某些情况下,将 JS 与 HTML 分开是不合需要的,即 `<b onclick="this.nextElementSibling.innerHTML+='X'"><div></div>` 加载如果将其分开,AJAX 就意味着竞争风险(以及意外的复杂性)。出于扩展原因,分离是有好处的,但有些代码可以通过设计来密封。内容属性和 IDL 属性的存在都是有原因的。 (2认同)

Ric*_*ood 19

这并不能准确回答问题,但如果用例允许移动元素而不是复制它,则可以将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);
}
Run Code Online (Sandbox Code Playgroud)

  • PS 看来 `removeChild()` 步骤是不必要的。 (10认同)