Обработчик для динамически создаваемых DOM-узлов при их вставке - PullRequest
8 голосов
/ 20 марта 2012

Мне нравится запускать пользовательские сценарии на страницах, которыми я не владею или не контролирую.Много раз на этих страницах динамически создавался контент, к которому я хотел бы применить функцию.

Возможно ли это?Если так, как я могу это сделать?В идеале я ищу какой-то живой метод jQuery live, за исключением того, что вместо привязки события, подобного click, это больше похоже на событие, которое происходит, когда элемент загружается в DOM.Событие load будет работать для некоторых элементов, но я не думаю, что для всех ...

В этом вопросе предположим, что вы не можете посмотреть или изменить код, вставляющий узлы DOM.Я хотел бы использовать технику, которую я мог бы использовать в сценарии пользователя или в букмарклете, который можно было бы использовать на нескольких не связанных сайтах.

Редактировать: Я ищу что-то, что можно использовать в моей закладке инвертированных цветов: JavaScript: Invertцвет на всех элементах страницы

Ответы [ 5 ]

10 голосов
/ 20 марта 2012

Если вы используете браузер, такой как Firefox или Chrome, вы можете прослушать событие DOMNodeInserted:

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

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

Fiddle: http://jsfiddle.net/VeF6g/ (возможно, не работает в IE)

Обновление : Событие устарело. Вы должны использовать 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();

Больше информации здесь: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

3 голосов
/ 03 ноября 2016

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

<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>
3 голосов
/ 27 января 2014

Если у вас нет доступа к библиотеке, такой как jQuery , вот синтаксис только в: JavaScript :

document.addEventListener('DOMNodeInserted', nodeInsert)

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

Я думаю, что это должно работать в большинстве браузеров.

1 голос
/ 20 марта 2012

Общий способ обнаружения вставки узла - использовать событие мутации DOMNodeInserted.

Меня интересует каждый узел. Я меняю цвета всего на странице.

Для этой цели лучшим решением является внедрение динамической таблицы стилей, для которой достаточно флага !important. Если вы хотите изменить только цвета, я рекомендую вместо * GreaseMonkey расширение Стильный ( Стильный для Chrome ).

1 голос
/ 20 марта 2012

Это довольно сложно сделать, потому что нет жизнеспособного события для реагирования на изменения DOM. Я бы предпочел вместо этого придерживаться делегирования событий.

Но есть некоторые события, которые вы можете найти полезными или интересными. В списке DOM-событий Mozilla Developer Network вы можете видеть, например ::

  • DOMNodeInserted
  • DOMNodeInsertedIntoDocument
  • DOMNodeRemoved
  • DOMElementNameChanged

Однако все они помечены как черновики W3C.

...