Подтвердить что ты не робот

Альтернатива DOMNodeInserted

DOMNodeInserted, как известно, замедляет динамические страницы, MDN даже рекомендует не использовать его вообще, но не предоставляет никаких альтернатив.

Мне не интересен элемент, вставленный, мне просто нужно знать, когда какой-то script изменяет DOM. Есть ли лучшая альтернатива слушателям событий мутации (возможно, getElementsByTagName внутри nsiTimer)?

4b9b3361

Ответ 1

Если вы создаете веб-приложение, предназначенное для последних мобильных телефонов и более новых версий браузеров (Firefox 5+, Chrome 4+, Safari 4+, iOS Safari 3+, Android 2.1+), вы можете использовать следующий код для создать потрясающее событие для вставки dom-узлов, и он даже запускается на узлах изначально на странице статической маркировки страницы!

Здесь ссылка на полный пост с и пример: http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/

Замечание о наблюдателях мутаций:, в то время как новые функции Mutation Observers в последних браузерах отлично подходят для мониторинга простых вставок и изменений в DOM, поймите, что этот метод можно использовать, чтобы сделать гораздо больше, поскольку он позволяет вам следить за любым совпадением правил CSS, которое вы можете использовать. Это очень мощно для многих случаев использования, поэтому я завернул это в библиотеку здесь: https://github.com/csuwildcat/SelectorListener

Вам нужно будет добавить соответствующие префиксы к имени события CSS и animationstart, если вы хотите настроить таргетинг на различные браузеры. Вы можете прочитать больше об этом в сообщении, связанном с выше.

Основной node вставной футляр

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);

Прослушивание более сложных селекторных совпадений:

Это позволяет сделать вещи, которые почти невозможно сделать с наблюдателями мутаций

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);

Ответ 2

Одна новая альтернатива, о которой кратко упомянул @naugtur, MutationObserver. Он предназначен для замены устаревших мутационных событий, если браузер (ы), который вы разрабатываете для поддержки (например, если вы разрабатываете расширение браузера).

Ответ 3

Та же самая методика, что и описанная csuwldcat, была превращена в простой в использовании плагин jQuery (если это ваша вещь): https://github.com/liamdanger/jQuery.DOMNodeAppear p >

Ответ 4

Здесь публикуется этот вопрос, потому что этот вопрос - это то место, где я приземлился, ища помощь с DOMNodeInserted с ошибкой с IE9, но обратите внимание, что это решение специально для ситуации, когда jQuery используется в контексте ASP.NET, который использует функцию End Request, Ваш пробег может отличаться и т.д.

В принципе, мы собираемся полностью удалить DOMNodeInserted и использовать End Request для загрузки нашего обработчика событий:

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
});

Ответ 5

Если все, что вы хотите сделать, это инициировать событие при изменении 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);