Определение того, был ли элемент HTML добавлен в DOM динамически

Есть ли способ в Javascript или jQuery, чтобы узнать, когда элемент HTML был добавлен в DOM динамически, либо через jQuery.append(), либо один из собственных манипуляторов Javascript node? Возможно, существует несколько разных способов добавления элементов HTML на страницу динамически, поэтому я не уверен, какие события или события я должен прослушивать.

Конкретный пример состоит в том, что тег привязки добавляется на страницу с помощью стороннего Javascript-кода (который я не могу изменить или легко просветить). Я хочу изменить текст ссылки.

Я надеюсь, что есть что-то лучше, чем цикл setTimeout() на $(SOME ELEMENT).length > 0. (часть которого я видел в Как определить, был ли добавлен динамически созданный элемент DOM в DOM?, но он с 2008 года)

Ответ 1

Вы можете использовать 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 вместо этого.

Ответ 2

Основываясь на методе Даниэля Бюхнера, я создал небольшую библиотеку, чтобы поймать вставки 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

Ответ 3

Почему бы вам не попробовать? Я не помню точной функции, которую я использовал, но это похоже на это...

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

Добавление класса 'alertInsertion' в css страницы с вызовом анимации __nodeInserted.

Если анимация запущена, она удаляет класс из элемента и отправляет собственное событие с именем elementInserted, которое включает в себя элемент, который его вызвал.

просто используйте его, добавив прослушиватель событий:

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

и добавление класса .alertInsertion к любым элементам, которые вы хотите вызвать.

Если элемент получил еще один класс с анимацией, он будет запущен после удаления этого класса.