jQuery: обработка динамически добавленных элементов c DOM Mutation Observer

четверг, 18 декабря 2014 г.

Большинство статей на тему динамически созданных элементов сводятся к использованию метода .on() в jquery. И он бесспорно хорош, но только для случаев, когда надо на элементы вешать события.

Пример:

$('div.parent').on('click', 'input', function(){
    // творим магию тут
});

Этот код означает, что как только в DOM дереве внутри div с классом parent появляется любой input, то для него будет отрабатывать написанный нами обработчик клика.

Но что делать, когда не нужно «вешать» события на элемент?
Поясню. Мне понадобилось для элементов input с классом copy всегда производить одну и ту же манипуляцию – брать текущее значение value и копировать его в спрятанный div. Элемент input может уже быть на странице, а может и появиться в модальном окне после выполнения ajax-запроса. То есть надо «слушать» изменения DOM-дерева и как только появляется нужный мне элемент – проводить над ним манипуляции. Событий типа «oncreate» или подобных для DOMElement нет. Нашел событие DOMNodeInserted, но текущий статус depricated, значит больше не поддерживается, да и по факту на свежем Chrome оно не сработало.

Ответ я в итоге нашел, так что сэкономлю вам время.

Современный и рабочий способ решить описанную выше задачу – использовать DOM Mutation Observer.

Короткий пример:

// select the target node
var target = $('#some-id');
 
// create an observer instance
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        console.log(mutation.type);
    });
});
 
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true }
 
// pass in the target node, as well as the observer options
observer.observe(target, config);
 
// later, you can stop observing
observer.disconnect();

Подробнее – http://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/

Если нет желания разбираться и самому писать код, то есть прекрасный плагин arrive.js (https://github.com/uzairfarooq/arrive/), который использует как раз Mutation Observer.

Выйдет что-то подобное:

$(document).arrive("input.copy", function() {
    // $(this) - текущий элемент
});

В IE младше 11 версии не заработает.

Надеюсь, кому-нибудь поможет эта статья. Предложения/пожелания/вопросы – в комментарии.

Copyright © 2010 WEB IT blog