javascript 插入时动态创建的 DOM 节点的处理程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9778962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 07:48:48  来源:igfitidea点击:

Handler for dynamically created DOM nodes as they are inserted

javascriptjquerydombookmarkletuserscripts

提问by Muhd

I enjoy running custom scripts on pages that I do not own or control. Many times these pages have dynamically created content that I would like to apply a function to.

我喜欢在我不拥有或控制的页面上运行自定义脚本。很多时候,这些页面动态创建了我想对其应用函数的内容。

Is this possible? If so, how can I do this? Ideally I am looking for something live jQuery's livemethod, except instead of binding an event like clickit would be more like an event that happens when the element is loaded in the DOM. loadevent would work for some elements but I don't think for all...

这可能吗?如果是这样,我该怎么做?理想情况下,我正在寻找一些实时的 jQuerylive方法,除了绑定一个事件,就像click它更像是在 DOM 中加载元素时发生的事件。 load事件适用于某些元素,但我不认为所有...

For this question, assume that you cannot look at or change the code that is inserting the DOM nodes. I would like a technique that I could use in a userscript or bookmarklet that could be used across multiple unrelated sites.

对于这个问题,假设您无法查看或更改插入 DOM 节点的代码。我想要一种可以在用户脚本或书签中使用的技术,可以在多个不相关的网站上使用。

Edit: I am looking for something to use on my invert colors bookmarklet: JavaScript: Invert color on all elements of a page

编辑:我正在寻找可以在我的反转颜色书签上使用的东西:JavaScript:反转页面所有元素的颜色

回答by nrabinowitz

Assuming you're running a browser like Firefox or Chrome, you could listen for the DOMNodeInsertedevent:

假设您运行的是 Firefox 或 Chrome 等浏览器,您可以监听该DOMNodeInserted事件:

$(document).on('DOMNodeInserted', function(e) {
    $(e.target).css({ color : '#c00' });
});

$('body').append('<div>test</div>');?

Fiddle: http://jsfiddle.net/VeF6g/(probably fails in IE)

小提琴:http: //jsfiddle.net/VeF6g/(可能在 IE 中失败)

Update: The event is deprecated. You should use a MutationObserver:

更新:该事件已被弃用。您应该使用 MutationObserver:

var observer = new MutationObserver(function(mutationList) {
    for (var mutation of mutationList) {
        for (var child of mutation.addedNodes) {
            child.style.color = '#c00';
        }
    }
});
observer.observe(document, {childList: true, subtree: true});

// ready? Then stop listening with
observer.disconnect();

More information here: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

更多信息:https: //developer.mozilla.org/en-US/docs/Web/API/MutationObserver

回答by Balthazar

If you don't have access to a library like jQuery, here is the syntax in only-JavaScript:

如果您无法访问像jQuery这样的库,这里是仅JavaScript 中的语法:

document.addEventListener('DOMNodeInserted', nodeInsert)

function nodeInsert () {
  event.srcElement.style.color = '#ffffff'
}

I think it should work in most browsers.

我认为它应该适用于大多数浏览器。

回答by NR Ganesh

Here is one nice way to handle the node insertion event. set animations for the element that you are going to add using css.

这是处理节点插入事件的一种好方法。为要使用 css 添加的元素设置动画。

<style type="text/css">

/* set up the keyframes; remember to create prefixed keyframes too! */

@keyframes nodeInserted {  
from { opacity: 0.99; }
to { opacity: 1; }  
}

#parent > button {
animation-duration: 0.001s;
animation-name: nodeInserted;
}

</style>

#parent is the id for the div, in which i am going to append button's dynamically.

#parent 是 div 的 id,我将在其中动态附加按钮。

<script type="text/javascript">

    var insertListener = function(event){
        if (event.animationName == "nodeInserted") {
            // This is the debug for knowing our listener worked!
            // event.target is the new node!
            console.warn("Another node has been inserted! ", event, event.target);
        }
    }

    document.addEventListener("animationstart", insertListener, false); // standard + firefox
    document.addEventListener("MSAnimationStart", insertListener, false); // IE
    document.addEventListener("webkitAnimationStart", insertListener, false); // Chrome + Safari

    setInterval(function(){

        var btn = document.createElement("BUTTON");

        var t = document.createTextNode("CLICK ME");       // Create a text node

        btn.appendChild(t);         

        document.getElementById("parent").appendChild(btn);

    }, 2000);

</script>

回答by Tadeck

This is rather difficult to accomplish, because there is no viable event for reacting to DOM changes. I would rather stick to event delegation instead.

这很难实现,因为没有可行的事件来响应 DOM 更改。我宁愿坚持事件委托。

But there are some events that you may find useful or interesting. On Mozilla Developer Network's list of DOM eventsyou can see eg.:

但是有些事件您可能会觉得有用或有趣。在Mozilla Developer Network 的 DOM 事件列表中,您可以看到例如:

  • DOMNodeInserted,
  • DOMNodeInsertedIntoDocument,
  • DOMNodeRemoved,
  • DOMElementNameChanged,
  • DOMNodeInserted,
  • DOMNodeInsertedIntoDocument,
  • DOMNodeRemoved,
  • DOMElementNameChanged,

All of them however are marked as W3C drafts.

然而,所有这些都被标记为 W3C 草案。

回答by Rob W

A generic way to detect node insertion is to use the DOMNodeInsertedmutation event.

检测节点插入的通用方法是使用DOMNodeInserted突变事件。

I am interested in every node actually. I am changing the colors of everything on the page.

我实际上对每个节点都感兴趣。我正在更改页面上所有内容的颜色。

For this purpose, a better solution is to inject a dynamic stylesheet, sufficed with the !importantflag. If you only want to change colors, I recommend the Stylishextension (Stylish for Chrome) instead of GreaseMonkey.

为此,更好的解决方案是注入一个带有!important标志的动态样式表。如果您只想更改颜色,我推荐使用Stylish扩展程序(Stylish for Chrome)而不是 GreaseMonkey。