当特定ID的元素被插入到DOM中时,最有效的检测方式是什么?

3
正如标题所述,我想检测某个id或CSS类的元素被插入到DOM中时的确切时间戳(并可能检测它何时被移除)。最明显的方法是定期轮询文档,通过使用要查找的元素的ID调用document.getElementById,但这种方法不太准确,如果我需要检测多个元素,则可能会非常消耗性能。我看了一下Mutation EventsMutation Observers,但据我了解,为了检测元素是否已插入或已删除,我必须向根DOM元素添加监听器,这可能会严重影响性能,如果每次从页面插入或删除元素时都需要执行其他JS。是否有更优化的解决方案我不知道?此外,我希望不使用外部JS库,甚至不使用jQuery。

1
我觉得你已经回答了自己的问题。除非你要钩入插入函数,否则你必须要注意它。在那个时候,不再是关于最高效的方法,而是关于你是否能承受额外开销的问题。 - isherwood
1
如果你确定在运行代码时不会添加元素,那么你可以在处理代码时移除监听器,然后在完成后再添加监听器。 - juvian
也许使用querySelectorAll("#a,#b,#c,#d")会比4个getElementById()调用更快... 或者,你可以通过QSA("[id]").length来判断是否需要找到具体的元素... 另外,也许只是self.a比document.getElementById("a")更快... - dandavis
2个回答

5

原来有一种更高效的方法来检测特定节点的插入,可以使用CSS动画事件。

您可以将一个不可感知的动画定义为您要监听的类,比如说widget_inserted

@keyframes widget_inserted {  
    from { z-index: 1; }
    to { z-index: 1; }   
}

.widget {
    animation-duration: 0.001s;
    animation-name: widget_inserted;
}

我选择了z-index属性,因为在大多数情况下,它对插入的元素几乎没有任何额外的影响。结合非常短的动画持续时间,这些添加的CSS属性应该不会对原始文档产生任何其他更改。
因此,现在如果您将一个animationstart事件侦听器附加到文档,您应该能够捕获具有widget类的元素插入的确切时刻:
document.addEventListener('animationstart', function(event) {
    if (event.animationName == 'widget_inserted') {
        ...
    }
});

你可以在这里查看实时的演示


1
我喜欢这个!我把它转化成了一个函数,用来更新样式表,以便加载到DOM中的任何内容。 - T.CK

1
iframe元素会触发load/unload事件。您可以在要监视的元素中插入一个“哑”iframe,然后自己触发原始元素中的“load”事件。
function watch($ele){
    var $iframe = document.createElement('iframe');
    $iframe.style.display = 'none';
    $ele.appendChild($iframe);
    $iframe.addEventListener('load', function(){
      var event = new CustomEvent('load');
      $ele.dispatchEvent(event);
    });
}

完整的示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接