Запустить событие jQuery при изменении div - PullRequest
58 голосов
/ 12 февраля 2011

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

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

Я использую jQuery. Есть ли способ запечатлеть событие, которое изменило содержание этого div, однако это случилось?

Ответы [ 3 ]

70 голосов
/ 12 февраля 2011

Вы можете использовать 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>Hello, world!</h1><p>This is an example.</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>"]

Обновление 2

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

7 голосов
/ 12 февраля 2011

попробуйте что-то вроде этого ...

    $('#divId').bind('DOMNodeInserted', function(event) {
             alert('inserted ' + event.target.nodeName + // new node
           ' in ' + event.relatedNode.nodeName); // parent
       });

IE не поддерживает это свойство, но я думаю, что самым близким к нему является событие propertychange, которое запускается в ответ на изменение атрибутаили CSS-свойство элемента, но оно не срабатывает в ответ на изменение innerHTML, которое было бы близко к тому, что вы хотели.

еще одним возможным решением является переопределение функции манипуляции в jquery ...

Посмотрите на это обсуждение .. Предпочтительный способ изменения элементов, которые еще не созданы (кромесобытия)

1 голос
/ 12 февраля 2011

Нет ни такого события (onChange) ни в javascript, ни в jQuery, вам бы пришлось создать собственное событие.

Одним из решений может быть использование lowpro для присоединения поведения к этому элементу, которым вы хотите управлять, это поведение будет сериализовать элемент и затем создать опрос, который проверяет каждые x миллисекунд, чтобы увидеть, изменился ли элемент, если изменился, затем вызвать Ваше пользовательское событие на этом элементе.

У вас есть несколько примеров использования lowpro с jQuery: http://www.learningjquery.com/2008/05/using-low-pro-for-jquery

Удачи!

...