簡體   English   中英

"如何使用事件偵聽器復制 DOM 節點?"

[英]How to copy a DOM node with event listeners?

我試過

node.cloneNode(true); // deep copy

cloneNode()不復制事件偵聽器。 實際上,一旦附加了DOM,就無法通過DOM獲取事件監聽器,因此您的選擇是:

  • 手動將所有事件偵聽器添加到克隆節點
  • 重構您的代碼以使用事件委派,以便所有事件處理程序都附加到包含原始和克隆的節點
  • 使用Node.addEventListener()周圍的包裝函數來跟蹤添加到每個節點的偵聽器。 例如,這就是jQuery的clone()方法能夠使用其事件偵聽器復制節點的方式。

事件委派示例。

閱讀Tim Down的回答后,我發現委派的事件很容易實現,解決了我遇到的類似問題。 我想我會添加一個具體的例子,雖然它是在JQuery而不是Dojo。

我在Semantic UI中重新創建了一個應用程序,它需要一小段JS來使消息關閉按鈕工作。 但是,使用庫中的document.importNode從HTML模板標記克隆消息。 這意味着即使我將事件處理程序附加到新HTML中的模板,它們也會在克隆過程中丟失。

我無法做Tim的選項1,只是在克隆過程中重新附加它們,因為消息傳遞庫與前端框架無關。 (有趣的是,我之前的前端是在Zurb Foundation,它使用了一個“數據可關閉”屬性,其功能在克隆過程中幸存下來)。

建議正常事件處理是這樣的

$('.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等價物在概念上看起來非常相似。

這並不完全回答這個問題,但如果用例允許移動元素而不是復制它,則可以將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編寫一些代碼。

我知道我遲到了,但這是一個對我有用的解決方案:

const originalButtons = original.querySelectorAll<HTMLElement>('button');
const cloneButtons = clone.querySelectorAll<HTMLElement>('button');
originalButtons.forEach((originalButton: HTMLElement, index: number) => {
  cloneButtons[index].after(originalButton);
  cloneButtons[index].remove();
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM