2009-09-19 9 views
15

Estoy intentando crear un evento especial de jQuery que se desencadena cuando cambia el contenido vinculado. Mi método es verificar el contenido con un setInterval y verificar si el contenido ha cambiado desde la última vez. Si tienes algún método mejor para hacerlo, avísame. Otro problema es que parece que no puedo borrar el intervalo. De todos modos, lo que necesito es la mejor manera de verificar los cambios de contenido con el evento. Especial.Crear un evento especial de jQuery para contenido modificado

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

})(); 

y se unen de esta manera:

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

tengo la console.log 'contenido cambiado', pero no el console.log 'contentchange desencadenó'. Por lo tanto, es obvio que la devolución de llamada nunca se desencadena.

Acabo de utilizar Firebug para cambiar el contenido y activar el evento, para probarlo.

actualización
no creo que hice esta bastante claro, mi código no funciona realmente. Estoy buscando lo que estoy haciendo mal.


Este es el código final para cualquier persona interesada

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

})(); 

Gracias a Mushex por ayudarme.

+0

algún motivo usted no está usando 'var' por $ esta declaración? –

+0

¿Y tiene una ortografía consistente de 'contenido original' en la página * real *? –

+0

Reparado. –

Respuesta

7

también echar un vistazo a James similar script (declarar como método de objeto jQuery y no como 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')); 
    }); 

}; 

y la creación de un evento especial

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

}; 

De todos modos, si lo necesita sólo como evento, tu guión es bueno :)

+0

Lo que estoy buscando es cómo crear un evento especial, como lo he hecho, solo uno que realmente funciona. ¿Puedes mostrarme eso? –

+0

Pensé que lo había resuelto y simplemente le traje este ejemplo para ver un enfoque un poco diferente a este problema. Si su script en realidad no funciona todavía, hágamelo saber. –

+0

Mi script no funciona. Sería genial si pudieras ayudarme a hacer que funcione :) Y, por cierto, gracias por el otro enfoque. –

4


Sé que esta publicación/pregunta es un poco antigua, pero en estos días estaba tan atrás imilar solución y encontré esto:

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

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

Esperanza esta ayuda a alguien!

+5

DOMMutations están privadas. –

+1

No vale la pena un voto negativo. Muchas cosas están en desuso, pero hasta que TODOS los navegadores ofrezcan una solución mejor, se seguirán usando y aún es útil de entender. (+1 voto compensado aquí) – mkoistinen

+0

limpio! ¡Mucho más limpio que un temporizador, incluso si está obsoleto! – TCHdvlp

1

El código final en la pregunta original funcionó para mí, ¡gracias! Solo me gustaría señalar que estoy usando jquery 1.9.1 y $ .event.handle parece haber sido eliminado. Cambié lo siguiente para que funcione.

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

a

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

0

tal vez usted podría intentar Mutación Observador

Éstos son el código:

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); 
Cuestiones relacionadas