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);
}