32

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

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

我希望有比setTimeout()循环更好的东西$(SOME ELEMENT).length > 0(我在如何确定是否将动态创建的 DOM 元素添加到 DOM 中看到了其中的一部分?但它是从 2008 年开始的)

4

4 回答 4

27

您可以为此目的使用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改为。

于 2013-05-17T22:41:25.907 回答
16

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

它使用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

于 2014-02-06T10:49:13.863 回答
8

你为什么不试试这个?我不记得我使用的确切功能,但它有点类似于这个......

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

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

元素添加到页面时的事件

于 2013-05-17T22:50:05.610 回答
3

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

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 类添加到要触发它的任何元素中。

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

于 2016-11-02T09:36:30.693 回答