2009-09-19 13 views
15

Sto provando a creare un evento speciale jQuery che si attiva quando il contenuto associato viene modificato. Il mio metodo è controllare il contenuto con un setInterval e controllare se il contenuto è cambiato dall'ultima volta. Se hai qualche metodo migliore per farlo, fammi sapere. Un altro problema è che non riesco a cancellare l'intervallo. Ad ogni modo, quello di cui ho bisogno è il modo migliore per verificare le modifiche del contenuto con event.special.Creare un evento speciale jQuery per il contenuto modificato

(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) 
     } 
    }; 

})(); 

e associarlo in questo modo:

$('#container').bind('contentchange', function() { 
     console.log('contentchange triggered'); 
}); 

ho la console.log 'contenuti cambiato', ma non il console.log 'contentchange attivato'. Quindi è ovvio che il callback non viene mai attivato.

mi basta usare Firebug per modificare il contenuto e per attivare l'evento, di provarlo.

Aggiornamento
non credo che ho fatto questo abbastanza chiaro, il mio codice in realtà non funziona. Sto cercando quello che sto facendo male.


Ecco il codice finito per chiunque sia interessato

(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); 
     } 
    }; 

})(); 

Grazie a Mushex per avermi aiutato.

+0

Qual è il motivo non lo si utilizza 'var' per $ questa dichiarazione? –

+0

E hai ortografia coerente di 'orginalContent' nella pagina * real *? –

+0

corretto. –

risposta

7

anche un'occhiata a James similar script (dichiarando come metodo di oggetto jQuery e non come evento)

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')); 
    }); 

}; 

e la creazione di un evento speciale

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'); 
    } 

}; 

In ogni caso, se ne avete bisogno solo come evento, si script è bello :)

+0

Quello che sto cercando è come creare un evento speciale, come ho fatto, solo uno che funziona realmente. Puoi mostrarmelo? –

+0

Pensavo avessi risolto e ti portassi questo esempio per vedere un approccio leggermente diverso a questo problema. Se il tuo script in realtà non funziona ancora, fammi sapere. –

+0

Il mio script non funziona. Sarebbe bello se tu potessi aiutarmi a farlo funzionare :) E a proposito, grazie per l'altro approccio. –

4


so che questo post/domanda è un po 'vecchio, ma in questi giorni ero dietro come soluzione analoghe sui e ho trovato questo:

$('#selector').bind('DOMNodeInserted', function(e) { 
    console.log(e.target); 
}); 

Fonte: http://naspinski.net/post/Monitoring-a-DOM-Element-for-Modification-with-jQuery.aspx

Spero che questo aiuto a qualcuno!

+5

DOMMutazioni sono private. –

+1

Difficilmente vale un downvote. Molte cose sono deprecate, ma fino a quando TUTTI i browser offrono una soluzione migliore, saranno comunque utilizzati, ed è ancora utile da capire. (+1 scostamento voto qui) – mkoistinen

+0

pulito! Molto più pulito di un timer anche se è deprecato! – TCHdvlp

1

Il codice finito nella domanda originale ha funzionato per me, grazie! Vorrei solo notare che sto usando jQuery 1.9.1 e $ .event.handle sembra essere stato rimosso. Ho cambiato il seguente modo per farlo funzionare.

jQuery.event.handle.call (auto, {type: 'contentchange'});

a

jQuery.event.dispatch.call (self, {type: 'contentchange'});

0

Forse si potrebbe provare Mutazione Observer

Ecco il codice:

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); 
Problemi correlati