Отловить изменение содержимого div

285
18 июля 2017, 19:39

У меня есть div, содержимое которого может меняться различными способами: например, весь его контент может быть изменён через innerHTML, или могут быть добавлены узлы через DOM-методы. Это может произойти через собственный javascript или через вызовы jQuery API, или через другие библиотеки.

Я хочу выполнить некоторый код, когда содержимое div изменится, но я абсолютно не контролирую, когда он изменится. Действительно, я разрабатываю плагин, который может использоваться другими людьми, которые могут свободно изменять содержимое своих div'ов так, как они предпочитают. Когда внутреннее содержимое этого div изменяется, форма плагина также может быть обновлена.

Я использую jQuery. Есть ли способ отловить изменение содержимого div?

Answer 1

MutationObserver (поддержка)

const observer = new MutationObserver(mutations => console.log(mutations)); 
observer.observe(test, {  
  attributes: true,  
  childList: true,       
  characterData: true, 
  subtree: true 
}); 
 
test.innerHTML = '1'; 
test.classList.add('test'); 
test.appendChild(document.createElement('br')); 
test.innerHTML += '2';
<div id='test'></div>

Answer 2

Вы можете использовать DOMNodeInserted и DOMNodeRemoved, чтобы проверить, добавлены или удалены элементы. К сожалению, IE не поддерживает это.

$('#myDiv').bind('DOMNodeInserted DOMNodeRemoved', function(event) {
    if (event.type == 'DOMNodeInserted') {
        alert('Content added! Current content:' + '\n\n' + this.innerHTML);
    } else {
        alert('Content removed! Current content:' + '\n\n' + this.innerHTML);
    }
});

Можно сохранить исходное содержимое и будущие изменения с помощью .data(). Вот пример.

var div_eTypes = [],
    div_changes = [];
$(function() {
    $('#myDiv').each(function() {
        this['data-initialContents'] = this.innerHTML;
    }).bind('DOMNodeInserted DOMNodeRemoved', function(event) {
        div_eTypes.concat(e.type.match(/insert|remove/));
        div_changes.concat(this.innerHTML);
    });
});

Пример вывода:

> $('#myDiv').data('initialContents');
"<h1>Привет мир!</h1><p>Это пример.</p>"
> div_eTypes;
["insert", "insert", "remove"]
> div_changes;
["<iframe src='http://example.com'></iframe>", "<h4>IANA — Example domains</h4><iframe src='http://example.com'></iframe>", "<h4>IANA – Example domains</h4>"]

Возможно, вы захотите включить DOMSubtreeModified, так как DOMNodeInserted и DOMNodeRemoved не запускаются, если элементы заменены через innerHTML. Он не работает в IE, но, по крайней мере, он отлично работает в других браузерах.

READ ALSO
Как связать чекбокс с вызовом метода? [дубликат]

Как связать чекбокс с вызовом метода? [дубликат]

На данный вопрос уже ответили:

254
jquery не подхватывает ссылку с json [дубликат]

jquery не подхватывает ссылку с json [дубликат]

На данный вопрос уже ответили:

265
Поправить работу функции по событию change jquery

Поправить работу функции по событию change jquery

У меня есть input, в который нужно ввести число

387
передача данных из одного запроса в другой

передача данных из одного запроса в другой

Выводит: "Результат1: 35; результат2: 38," "Результат1: 22; результат2: 22, " " итого: 73" " итого: 44"

254