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