Обнаружение изменений содержимого элемента с помощью jQuery
change()
Функция работает и обнаруживает изменения в элементах формы, но есть ли способ определить, когда содержимое элемента DOM было изменено?
Это не работает, если #content
это элемент формы
$("#content").change( function(){
// do something
});
Я хочу, чтобы это срабатывало при выполнении чего-то вроде:
$("#content").html('something');
Также html()
или же append()
функция не имеет обратного вызова
Какие-либо предложения?
15 ответов
Это мутационные события.
Я не использовал API-интерфейсы событий мутации в jQuery, но беглый поиск привел меня к этому проекту на GitHub. Я не знаю о зрелости проекта.
Я знаю, что этому посту исполнился год, но я бы хотел предложить иной подход к решению для тех, у кого похожая проблема:
Событие изменения jQuery используется только для пользовательских полей ввода, потому что, если что-то еще обрабатывается (например, div), эта манипуляция исходит из кода. Итак, найдите, где происходит манипуляция, а затем добавьте туда все, что вам нужно.
Но если это невозможно по какой-либо причине (вы используете сложный плагин или не можете найти какие-либо возможности "обратного вызова"), то я бы предложил следующий подход jQuery:
а. Для простой манипуляции с DOM используйте jQuery цепочки и обходы,
$("#content").html('something').end().find(whatever)....
б. Если вы хотите сделать что-то еще, используйте JQuery's
bind
с пользовательским событием иtriggerHandler
$("#content").html('something').triggerHandler('customAction'); $('#content').unbind().bind('customAction', function(event, data) { //Custom-action });
Вот ссылка на обработчик триггера jQuery: http://api.jquery.com/triggerHandler/
Как насчет http://jsbin.com/esepal/2
$(document).bind("DOMSubtreeModified",function(){
console.log($('body').width() + ' x '+$('body').height());
})
Это событие устарело в пользу API наблюдателя мутации
Браузер не будет запускать событие onchange для <div>
элементы.
Я думаю, что причина этого в том, что эти элементы не изменятся, если не будут изменены javascript. Если вам уже нужно изменить элемент самостоятельно (а не пользователь, делающий это), то вы можете просто вызвать соответствующий сопровождающий код одновременно с изменением элемента, например, так:
$("#content").html('something').each(function() { });
Вы также можете вручную запустить событие, подобное этому:
$("#content").html('something').change();
Если ни одно из этих решений не подходит для вашей ситуации, не могли бы вы дать больше информации о том, что вы конкретно пытаетесь достичь?
Попробуй привязать к DOMSubtreeModified
Событие seeign as test также является частью DOM.
см. этот пост здесь на SO:
Попробуйте это, это было создано Джеймсом Падолси (JP здесь на SO) и делает именно то, что вы хотите (я думаю)
http://james.padolsey.com/javascript/monitoring-dom-properties/
Это не совсем ответ JQuery - но полезно упомянуть для отладки.
В Firebug вы можете щелкнуть правой кнопкой мыши по элементу в дереве DOM и установить "Break on Attribute Change":
Когда атрибут изменяется в скрипте, появляется окно отладки, и вы можете отследить, что происходит. Ниже также есть опция для вставки элемента и удаления элемента (бесполезно скрыта всплывающим окном на снимке экрана).
Я разрабатываю крошечную библиотеку JS под названием mutabor ( https://github.com/eskat0n/mutabor), предназначенную для упрощения использования событий мутации DOM. Смотрите demo.html для примеров.
Попробуйте плагин livequery. Кажется, это работает для чего-то подобного, что я делаю.
Зачастую простым и эффективным способом достижения этого является отслеживание того, когда и где вы модифицируете DOM.
Вы можете сделать это, создав одну центральную функцию, которая всегда отвечает за изменение DOM. Затем вы выполняете необходимую очистку измененного элемента из этой функции.
В недавнем приложении мне не требовалось немедленных действий, поэтому я использовал обратный вызов для функции handly load(), чтобы добавить класс к любым измененным элементам, а затем обновлять все измененные элементы каждые несколько секунд с помощью таймера setInterval.
$($location).load("my URL", "", $location.addClass("dommodified"));
Тогда вы можете справиться с этим, как вы хотите - например,
setInterval("handlemodifiedstuff();", 3000);
function handlemodifiedstuff()
{
$(".dommodified").each(function(){/* Do stuff with $(this) */});
}
Вы можете добавить опцию обратного вызова в функцию html (или любую другую):
$.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");});
Вы вносите изменения в некоторый элемент, а элемент не вынужден меняться чем-то, что вам нужно поймать.
Я написал фрагмент, который проверит изменения элемента в событии.
Так что, если вы используете сторонний javascript-код или что-то еще, и вам нужно знать, когда что-то появляется или изменяется после нажатия, тогда вы можете.
Для приведенного ниже фрагмента предположим, что вам нужно знать, когда изменяется содержимое таблицы после нажатия кнопки.
$('.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);
});
Псевдокод:
- Как только вы нажмете кнопку
- захватывается HTML-код элемента, который вы ожидаете изменить
- Затем мы постоянно проверяем HTML элемента
- когда мы находим html другим, мы прекращаем проверку
Мы можем достичь этого, используя Mutation Events. Согласно www.w3.org, модуль событий мутации предназначен для уведомления о любых изменениях в структуре документа, включая изменения атрибутов и текста. Для более подробной информации MUTATION EVENTS
Например:
$("body").on('DOMSubtreeModified', "#content", function() {
alert('Content Modified'); // do something
});
Я думаю, что это невозможно, то есть событие изменилось, но это, конечно, не x-browser
Должен ли я сказать, что это невозможно без некоторого неприятного интервала, уходящего на задний план!