Вопрос по dom, jquery, javascript – Обнаружение изменений содержимого элемента с помощью jQuery

111

change() Функция работает и обнаруживает изменения в элементах формы, но есть ли способ определить, когда содержимое элемента DOM было изменено?

Это не работает, если#content это элемент формы

$("#content").change( function(){
    // do something
});

Я хочу, чтобы это срабатывало при выполнении чего-то вроде:

$("#content").html('something');

Такжеhtml() или жеappend() функция не имеет обратного вызова.

Какие-либо предложения?

старый вопрос, который я знаю, но проверьте мой ответ для элегантного решенияstackoverflow.com/a/23826615/744975 Andrew Atkinson

Ваш Ответ

15   ответов
7
Привет из будущего. Это кросс-браузер сейчас (2015).
@MarcG обновил ответ Elzo Valugi
2

https://github.com/eskat0n/mutabor), который предназначен для упрощения использования DOM Mutation Events. Смотрите demo.html для примеров.

0

Mutation Events, Согласно www.w3.org, модуль события мутации предназначен для уведомления о любых изменениях в структуре документа, включая изменения атрибутов и текста. Для более подробной информацииMUTATION EVENTS

Например :

$("body").on('DOMSubtreeModified', "#content", function() {
    alert('Content Modified'); // do something
});
Это уже давно устарело. Надо использоватьMutation Observers (та же концепция)
@CarlesAlcolea Спасибо за обновление :)
70

что этому посту исполнился год, но я бы хотел предложить иной подход к решению для тех, у кого похожая проблема:

The jQuery change event is used only on user input fields because if anything else is manipulated (e.g., a div), that manipulation is coming from code. So, find where the manipulation occurs, and then add whatever you need to there.

But if that's not possible for any reason (you're using a complicated plugin or can't find any "callback" possibilities) then the jQuery approach I'd suggest is:

a. For simple DOM manipulation, use jQuery chaining and traversing, $("#content").html('something').end().find(whatever)....

b. If you'd like to do something else, employ jQuery's bind with custom event and triggerHandler

$("#content").html('something').triggerHandler('customAction');

$('#content').unbind().bind('customAction', function(event, data) {
   //Custom-action
});

Вот ссылка на обработчик триггера jQuery:http://api.jquery.com/triggerHandler/

+1 & quot; Найдите, где происходит манипуляция, а затем добавьте туда все, что вам нужно. & Quot; Исправил мою проблему за 2 секунды без каких-либо хаков / плагинов :)
Единственное изменение, которое я предлагаю здесь, это то, чтоbind ожидает, что ваш обработчик вернетbool.
последняя мысль хотя выше это должно быть довольно полным: вы можете обновить значение скрытого поля ввода значением #content html, а затем связать событие изменения со скрытым полем ввода :) множество опций
13

<div> элементы.

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

 $("#content").html('something').each(function() { });

Вы также можете вручную запустить событие, подобное этому:

 $("#content").html('something').change();

Если ни одно из этих решений не подходит для вашей ситуации, не могли бы вы дать больше информации о том, чего вы конкретно пытаетесь достичь?

Это предполагает, что вы написали весь javascript, что может быть не так.
БЛАГОДАРЮ ВАС!!!! Это только помогло мне решить проблему, на которую я смотрел в течение 6 часов.
Именно то, что мне было нужно.
1

еживание того, когда и где вы модифицируете DOM.

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

В недавнем приложении мне не требовалось немедленных действий, поэтому я использовал обратный вызов для функции handly load (), чтобы добавить класс к любым измененным элементам, а затем обновлять все измененные элементы каждые несколько секунд с помощью таймера setInterval.

$($location).load("my URL", "", $location.addClass("dommodified"));

Тогда вы можете справиться с этим так, как хотите - например,

setInterval("handlemodifiedstuff();", 3000); 
function handlemodifiedstuff()
{
    $(".dommodified").each(function(){/* Do stuff with $(this) */});
}
Это предполагает, что вы написали весь javascript, что может быть не так.
3

В Firebug вы можете щелкнуть правой кнопкой мыши по элементу в дереве DOM и настроить «Разрыв при изменении атрибута»:

Element right-click in Firebug with Break on Attribute Change highlighted

Когда атрибут изменяется в скрипте, появляется окно отладки, и вы можете отследить, что происходит. Ниже также есть опция для вставки элемента и удаления элемента (бесполезно скрыта всплывающим окном на снимке экрана).

Это полезно, но не совсем то, о чем он просил. Это обнаружит такие вещи, как когда класс изменяется, или когда атрибут стиля добавляется или изменяется. Он не будет проверять, когда содержимое внутренней части узла изменяется. Например, если какой-то javascript где-то меняет узел с & lt; span & gt; hello & lt; / span & gt; to & lt; span & gt; World & lt; / span & gt ;, это не обнаружит его
Увидетьstackoverflow.com/a/11546242/988469 за отличный ответ.
15

http://jsbin.com/esepal/2

$(document).bind("DOMSubtreeModified",function(){
  console.log($('body').width() + ' x '+$('body').height());
})

This event has been deprecated in favor of the Mutation Observer API

неплохая идея, хотя мне интересно, сколько поддержки это имеет.developer.mozilla.org/en/DOM/DOM_event_reference/… Elzo Valugi
Ух, аккуратно !!! Спасибо!
Как вы контролируете конкретный элемент на предмет изменений? В настоящее время документ контролирует всю страницу.
1

угую):

$.fn.oldHtml = $.fn.html;
$.fn.html = function(html,fn){
  fn = fn || function(){};
  var result =  this.oldHtml(html);
  fn();
  return result;
};
$('body').html(11,function(){alert("haha");});

Демо здесь.

You do the change on some element, not the element is forced to change by something that you have to catch.

Я должен был решить эту проблему сегодня. Я не смог отредактировать код, который на самом деле вызывал html (), потому что он находится в сторонней библиотеке. Модифицированная версия этого была идеальна для меня. Я сделал это: $ .fn.oldHtml = $ .fn.html (); $ .fn.html = function (e) {var result = this.oldHtml (e); this.trigger ('afterHtmlChange', e);} Теперь я могу связать любые события, которые я хочу, с только что созданным событием afterHtmlChange для любого элемента, который будет срабатывать всякий раз, когда что-либо вызывает jQuery's html () fn.
Упс, небольшая ошибка. Fn в моем комментарии выше должно быть: function (e) {var result = this.oldHtml (e); this.trigger (& APOS; afterHtmlChange & APOS;, д); вернуть результат;}
10

DOMSubtreeModified Событие seeign как тест также является частью DOM.

см. этот пост здесь на SO:

как-ду-я-монитор-The-дом-для-изменений

10

он был создан Джеймсом Падолси (J-P здесь на SO) и делает именно то, что вы хотите (я думаю)

http://james.padolsey.com/javascript/monitoring-dom-properties/

Для кросс-браузерной версии Object.prototype.watch см.gist.github.com/384583
24

мутационные события.

Я не использовал API событий мутации в jQuery, но беглый поиск привел меня кэтот проект на GitHub. Я не знаю о зрелости проекта.

Этот плагин событий мутации не будет работать, потому что он просто перехватывает события в методах мутации jQuery. Они запускаются, когда сам jQuery пытается изменить элементы, но не когда элементы изменяются извне jQuery. Они не следят за изменениями в документе. Проверьте этот маленький плагин вместо этого:stackoverflow.com/questions/3233991/jquery-watch-div/…
Mutation events are deprecated; не используйте их.
Поиск в Google и публикация ссылки на библиотеку, которую вы никогда не пробовали, не очень полезны. (Комментируя, потому что мне было предложено при голосовании.)
Альтернативой мутационным событиям кажетсяMutationObservers.
0

Так что, если вы используете сторонний javascript-код или что-то еще, и вам нужно знать, когда что-то появляется или изменяется после нажатия, тогда вы можете.

For the below snippet, lets say you need to know when a table content changes after you clicked a button.

$('.button').live('click', function() {

            var tableHtml = $('#table > tbody').html();
            var timeout = window.setInterval(function(){

                if (tableHtml != $('#table > tbody').
                    console.log('no change');
                } else {
                    console.log('table changed!');
                    clearInterval(timeout);
                }

            }, 10);
        });

Псевдокод:

Once you click a button the html of the element you are expecting to change is captured we then continually check the html of the element when we find the html to be different we stop the checking
2

это работает для чего-то подобного, что я делаю.

http://docs.jquery.com/Plugins/livequery

-4

что это невозможно, то есть событие изменилось, но это определенно не x-browser

Должен ли я сказать, что это невозможно без некоторого неприятного интервала, пыхтящего на заднем плане!

невозможность - ничто!

Похожие вопросы