DOMNodeInserted 的替代方案

发布于 2024-11-28 16:36:24 字数 284 浏览 1 评论 0原文

众所周知,DOMNodeInserted 会使动态页面变慢,MDN 甚至建议不要完全使用它,但实际上并没有这样做。不提供任何替代方案。

我对插入的元素不感兴趣,我只需要知道某个脚本何时修改 DOM。是否有更好的替代突变事件侦听器(可能是 nsiTimer 内的 getElementsByTagName)?

DOMNodeInserted is known to make dynamic pages slow, MDN even recommends not using it altogether, but doesn't provide any alternatives.

I'm not interested in the element inserted, I just need to know when some script modifies the DOM. Is there a better alternative to mutation event listeners (maybe getElementsByTagName inside an nsiTimer)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

微凉徒眸意 2024-12-05 16:36:24

如果您正在创建一个针对最新手机和较新版本浏览器(Firefox 5+、Chrome 4+、Safari 4+、iOS Safari 3+、Android 2.1+)的 Web 应用程序,您可以使用以下代码创建一个很棒的 Web 应用程序:插入 dom 节点的事件,它甚至在页面静态标记最初部分的节点上运行!

以下是完整帖子的链接和示例: http:// /www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/

关于突变观察者的注意事项:最新浏览器中较新的 Mutation Observers 功能非常适合监视 DOM 的简单插入和更改,请务必了解此方法可以用于执行更多操作,因为它允许您监视任何与您匹配的 CSS 规则可以的事。这对于许多用例来说非常强大,所以我将其封装在一个库中: https://github.com /csuwildcat/SelectorListener

如果您想针对各种浏览器,则需要向 CSS 和animationstart 事件名称添加适当的前缀。您可以在上面链接的文章中阅读更多相关内容。

基本节点插入案例

CSS

@keyframes nodeInserted {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

div.some-control {
    animation-duration: 0.01s;
    animation-name: nodeInserted;
}

JavaScript

document.addEventListener('animationstart', function(event){
    if (event.animationName == 'nodeInserted'){
        // Do something here
    }
}, true);

侦听更复杂的选择器匹配:

这使得事情能够进行这对于 Mutation Observers CSS 几乎不可能做到

@keyframes adjacentFocusSequence {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

.one + .two + .three:focus {
    animation-duration: 0.01s;
    animation-name: adjacentFocusSequence;
}

JavaScript

document.addEventListener('animationstart', function(event){
    if (event.animationName == 'adjacentFocusSequence'){
        // Do something here when '.one + .two + .three' are 
        // adjacent siblings AND node '.three' is focused
    }
}, true);

If you are creating a web app that targets recent mobile phones and newer versions of browsers (Firefox 5+, Chrome 4+, Safari 4+, iOS Safari 3+, Android 2.1+), you can use the following code to create an awesome event for the insertion of dom nodes, and it even runs on the nodes initially part of the page's static mark-up!

Here's the link to the full post with and example: http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/

Note on Mutation Observers: while the newer Mutation Observers features in recent browsers are great for monitoring simple insertions and changes to the DOM, do understand that this method can be used to do far more as it allows you to monitor for any CSS rule match you can thing of. This is super powerful for many use-cases, so I wrapped this up in a library here: https://github.com/csuwildcat/SelectorListener

You'll need to add the appropriate prefixes to the CSS and animationstart event name if you want to target various browsers. You can read more about that in the post linked to above.

The basic node insertion case

CSS:

@keyframes nodeInserted {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

div.some-control {
    animation-duration: 0.01s;
    animation-name: nodeInserted;
}

JavaScript:

document.addEventListener('animationstart', function(event){
    if (event.animationName == 'nodeInserted'){
        // Do something here
    }
}, true);

Listening for more complex selector matches:

This enables things that are almost impossible to do with Mutation Observers

CSS:

@keyframes adjacentFocusSequence {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

.one + .two + .three:focus {
    animation-duration: 0.01s;
    animation-name: adjacentFocusSequence;
}

JavaScript:

document.addEventListener('animationstart', function(event){
    if (event.animationName == 'adjacentFocusSequence'){
        // Do something here when '.one + .two + .three' are 
        // adjacent siblings AND node '.three' is focused
    }
}, true);
温柔戏命师 2024-12-05 16:36:24

@naugtur 简要提到的一种新替代方案是 MutationObserver。如果您正在开发的浏览器支持它(例如您正在开发浏览器扩展),它被设计为已弃用的突变事件的替代品。

One new alternative that @naugtur briefly mentioned is MutationObserver. It's designed as a replacement for the deprecated mutation events, if the browser(s) you're developing for supports it (like if you're developing a browser extension).

没企图 2024-12-05 16:36:24

之所以发布此问题,是因为这个问题是我在 IE9 中寻求 DOMNodeInserted 失败帮助的地方,但请注意,此解决方案专门针对在使用 End Request 函数的 ASP.NET 上下文中使用 jQuery 的情况。您的里程可能会有所不同,等等......

基本上,我们将完全丢弃 DOMNodeInserted 并使用 End Request 来加载我们的事件处理程序:

OLD:

$(document).ready(function() {

$(document).bind('DOMNodeInserted', function(event){
My jQuery event handler...

 }); 
});

================= ==================

新:

function Ajax_EndRequest {
  function2();
}

function2 (a,b){
  My jQuery event handler...
}

$(document).ready(function(){
  add_endRequest(Ajax_EndRequest); //this is what actually invokes the function upon request end.

 My jQuery event handler...//REMOVED -- don't need this now
});

This is posted here because this question is where I landed looking for help with DOMNodeInserted failing with IE9, but please note this solution is specifically for a situation where jQuery is being used within an ASP.NET context that uses an End Request function. Your mileage may vary, etc....

Basically, we are going to throw away the DOMNodeInserted altogether and use End Request to load our event handler:

OLD:

$(document).ready(function() {

$(document).bind('DOMNodeInserted', function(event){
My jQuery event handler...

 }); 
});

===================================

NEW:

function Ajax_EndRequest {
  function2();
}

function2 (a,b){
  My jQuery event handler...
}

$(document).ready(function(){
  add_endRequest(Ajax_EndRequest); //this is what actually invokes the function upon request end.

 My jQuery event handler...//REMOVED -- don't need this now
});
心房的律动 2024-12-05 16:36:24

与 csuwldcat 描述的技术相同的技术已被制作成易于使用的 jQuery 插件(如果您喜欢的话): https: //github.com/liamdanger/jQuery.DOMNodeAppear

The same technique as csuwldcat described has been made into an easy to use jQuery plugin (if that's your thing): https://github.com/liamdanger/jQuery.DOMNodeAppear

万劫不复 2024-12-05 16:36:24

尝试使用 customElements,但不适用于已经创建的元素!

customElements.define( 'insertion-triggerable', class extends HTMLElement {
    connectedCallback() {
        console.log( 'connected' )
    }

    disconnectedCallback() {
        console.log( 'disconnected' )
    }

    adoptedCallback() {
        console.log( 'adopted' )
    }
} );

let element = document.createElement( 'insertion-triggerable' );

或者

customElements.define( 'insertion-triggerable', class extends HTMLDivElement {
    // --||--
}, { extends: 'div' } );

let divElement = document.createElement( 'div', { is: 'insertion-triggerable' } );

try to use customElements, but not for already created elements!

customElements.define( 'insertion-triggerable', class extends HTMLElement {
    connectedCallback() {
        console.log( 'connected' )
    }

    disconnectedCallback() {
        console.log( 'disconnected' )
    }

    adoptedCallback() {
        console.log( 'adopted' )
    }
} );

let element = document.createElement( 'insertion-triggerable' );

OR

customElements.define( 'insertion-triggerable', class extends HTMLDivElement {
    // --||--
}, { extends: 'div' } );

let divElement = document.createElement( 'div', { is: 'insertion-triggerable' } );
漫雪独思 2024-12-05 16:36:24

如果您只想在 DOM 更改时触发事件,请执行以下操作:

var nodes=document.getElementsByTagName('*')||document.all;

function domchange(){
    alert('Hello');
}

window.setInterval(function(){
    var newnodes=document.getElementsByTagName('*')||document.all;
    if(newnodes!=nodes){
        nodes=newnodes;
        domchange();
    }
},1);

If all you want to do is trigger an event when the DOM changes, do something like this:

var nodes=document.getElementsByTagName('*')||document.all;

function domchange(){
    alert('Hello');
}

window.setInterval(function(){
    var newnodes=document.getElementsByTagName('*')||document.all;
    if(newnodes!=nodes){
        nodes=newnodes;
        domchange();
    }
},1);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文