Создайте специальное событие jQuery для контента, измененного
Я пытаюсь создать специальное событие jQuery, которое запускает, когда связанный контент изменяется. Мой метод проверяет содержимое с помощью setInterval и проверяет, изменился ли контент с последнего раза. Если у вас есть лучший способ сделать это, дайте мне знать. Другая проблема заключается в том, что я не могу очистить интервал. Во всяком случае, мне нужен лучший способ проверить изменения контента с помощью event.special.
(function(){
var interval;
jQuery.event.special.contentchange = {
setup: function(data, namespaces) {
var $this = $(this);
var $originalContent = $this.text();
interval = setInterval(function(){
if($originalContent != $this.text()) {
console.log('content changed');
$originalContent = $this.text();
jQuery.event.special.contentchange.handler();
}
},500);
},
teardown: function(namespaces){
clearInterval(interval);
},
handler: function(namespaces) {
jQuery.event.handle.apply(this, arguments)
}
};
})();
И привяжите его так:
$('#container').bind('contentchange', function() {
console.log('contentchange triggered');
});
Я получаю содержимое console.log "изменено", но не консоль-менеджер "contentchange triggered". Поэтому очевидно, что обратный вызов никогда не запускается.
Я просто использую Firebug для изменения содержимого и запуска события, чтобы проверить его.
Обновление
Я не думаю, что я сделал это достаточно ясно, мой код на самом деле не работает. Я ищу то, что я делаю неправильно.
Вот готовый код для всех, кого интересует
(function(){
var interval;
jQuery.event.special.contentchange = {
setup: function(){
var self = this,
$this = $(this),
$originalContent = $this.text();
interval = setInterval(function(){
if($originalContent != $this.text()) {
$originalContent = $this.text();
jQuery.event.handle.call(self, {type:'contentchange'});
}
},100);
},
teardown: function(){
clearInterval(interval);
}
};
})();
Благодаря Mushex за то, что он помог мне.
Ответы
Ответ 1
также взгляните на James аналогичный script (объявляющий как метод объекта jquery, а не как событие)
jQuery.fn.watch = function( id, fn ) {
return this.each(function(){
var self = this;
var oldVal = self[id];
$(self).data(
'watch_timer',
setInterval(function(){
if (self[id] !== oldVal) {
fn.call(self, id, oldVal, self[id]);
oldVal = self[id];
}
}, 100)
);
});
return self;
};
jQuery.fn.unwatch = function( id ) {
return this.each(function(){
clearInterval( $(this).data('watch_timer') );
});
};
и создание специального события
jQuery.fn.valuechange = function(fn) {
return this.bind('valuechange', fn);
};
jQuery.event.special.valuechange = {
setup: function() {
jQuery(this).watch('value', function(){
jQuery.event.handle.call(this, {type:'valuechange'});
});
},
teardown: function() {
jQuery(this).unwatch('value');
}
};
В любом случае, если вам это нужно только как событие, вы script хороши:)
Ответ 2
Я знаю, что этот пост/вопрос немного старый, но в эти дни я был за аналогичным решением, и я нашел это:
$('#selector').bind('DOMNodeInserted', function(e) {
console.log(e.target);
});
Источник: http://naspinski.net/post/Monitoring-a-DOM-Element-for-Modification-with-jQuery.aspx
Надеюсь, что это поможет кому-то!
Ответ 3
Готовый код в исходном вопросе работал у меня, спасибо! Я хотел бы отметить, что я использую jquery 1.9.1 и $.event.handle, кажется, был удален. Я изменил следующее, чтобы заставить его работать.
jQuery.event.handle.call(self, {type: 'contentchange'});
к
jQuery.event.dispatch.call(self, {type: 'contentchange'});
Ответ 4
возможно, вы могли бы попробовать Mutation Observer
Вот код:
mainArea = document.querySelector("#main_area");
MutationObserver = window.MutationObserver;
DocumentObserver = new MutationObserver(function() {
//what you want to run
});
DocumentObserverConfig = {attributes: true, childList: true, characterData: true, subtree: true};
DocumentObserver.observe(mainArea, DocumentObserverConfig);