确定 HTML 元素是否已动态添加到 DOM 中

问题描述 投票:0回答:4

Javascript 或 jQuery 中是否有一种方法可以通过

jQuery.append()
或本机 Javascript 的节点操纵器之一来找出 HTML 元素何时动态添加到 DOM 中?可能有几种不同的方法可以动态地将 HTML 元素添加到页面,所以我不确定我应该监听哪个或哪些事件。

具体的例子是,第三方Javascript代码(我无法修改或轻松收集)将锚标记添加到页面。我想更改链接的文本。

我希望有比

setTimeout()
上的
$(SOME ELEMENT).length > 0
循环更好的东西。 (我在如何确定动态创建的 DOM 元素是否已添加到 DOM?中看到了其中的一部分,但它来自 2008 年)

javascript jquery
4个回答
37
投票

您可以使用 Mutation Observers 来实现此目的 - 至少如果您不需要支持 IE/Opera。

这是一个关于如何使用它们的简短示例(取自 html5rocks.com):

var insertedNodes = [];
var observer = new WebKitMutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        for(var i = 0; i < mutation.addedNodes.length; i++)
            insertedNodes.push(mutation.addedNodes[i]);
    })
});
observer.observe(document, {
    childList: true
});
console.log(insertedNodes);

注意

WebKit
前缀。您需要使用特定于浏览器的前缀。在 Firefox 中,它会是
Moz

2022 更新:您不需要使用

WebKit
Moz
作为前缀,因为大多数浏览器已经实现了它。现在可以通过
MutationObserver
访问它。


18
投票

基于 Daniel Buchner 的 技术我创建了一个小型库来捕获 DOM 插入。它比 hack 本身使用起来更舒服。

它使用css动画事件,因此它不是基于DOMMutationEvents,也不是Mutation Observer。所以它不会减慢页面速度,并且比 MutationObserver 拥有更广泛的支持。

它还有一个额外的好处,那就是能够使用您想要的任何 CSS 选择器

使用示例:

insertionQ('.content div').every(function(element){
    //callback on every new div element inside .content
});

如果您在 DOMReady 之后调用它,它将仅捕获新元素。

请参阅 https://github.com/naugtur/insertionQuery 了解更多选项


9
投票

你为什么不试试这个呢?我不记得我使用的确切函数,但它与这个有点相似......

$(document).bind('DOMNodeInserted', function(event) {
      alert('inserted ' + event.target.nodeName + // new node
            ' in ' + event.relatedNode.nodeName); // parent
});

此外,我在此链接中找到了一些其他选项:

元素添加到页面时的事件


4
投票

不确定是否有人仍在寻找这个,但我一直在寻找,这就是我最终使用的解决方案。

var __css = document.createElement("style");
__css.type = "text/css";
__css.innerHTML = '.alertInsertion {animation: __nodeInserted 0.001s !important; -o-animation: __nodeInserted 0.001s !important; -ms-animation: __nodeInserted 0.001s !important; -moz-animation: __nodeInserted 0.001s !important; -webkit-animation: __nodeInserted 0.001s !important;}'+
'@keyframes __nodeInserted {from{outline-color: #111;}to{outline-color: #000;}}'+
'@-moz-keyframes __nodeInserted {from{outline-color: #111;}to{outline-color: #000;}}'+
'@-webkit-keyframes __nodeInserted {from{outline-color: #111;}to{outline-color: #000;}}'+
'@-ms-keyframes __nodeInserted {from{outline-color: #111;}to{outline-color: #000;}}'+
'@-o-keyframes __nodeInserted {from{outline-color: #111;}to{outline-color: #000;}}';
document.body.appendChild(__css);

insertion_event = function(event){
    if (event.animationName == '__nodeInserted') {
        event.target.className = event.target.className.replace(/\balertInsertion\b/,'');
        document.dispatchEvent(new CustomEvent('elementInserted', {'target': event.target}));
    }
}

document.addEventListener('animationstart', insertion_event, false);
document.addEventListener('MSAnimationStart', insertion_event, false);
document.addEventListener('webkitAnimationStart', insertion_event, false);

通过调用 __nodeInserted 动画将“alertInsertion”类添加到页面的 CSS 中。

如果触发动画,它会从元素中删除该类,并发送一个名为 elementInserted 的自定义事件,其中包括触发它的元素。

只需添加事件监听器即可使用它:

document.addEventListener('elementInserted', function(e)
{
    //Do whatever you want with e.target here.
});

并将 .alertInsertion 类添加到您想要触发它的任何元素。

如果元素有另一个带有动画的类,它将在删除该类后运行。

© www.soinside.com 2019 - 2024. All rights reserved.