2010-07-13 28 views
30

¿Hay alguna manera de mirar, si el contenido dentro de un div cambia?jQuery watch div

Digamos que tengo:

<div id="hello"><p>Some content here</p></div> 

cual en algún punto 5 segundos más tarde cambia a:

<div id="hello"><ul><li>This is totally different!</li></ul></div> 

¿Cómo puedo recibir notificaciones de este a través de una devolución de llamada o algo más? En la mayoría de los casos, puedo obtener el javascript que está haciendo la inserción, para decirme. Pero quería saber si era posible.

+6

¿Existe una razón por la que la función que cambia el contenido div no puede alertarte? – Josiah

Respuesta

63

El .Cambiar jQuery() método sólo funciona para los campos de formulario.

escribí un pequeño plugin de jQuery para usted:

<!-- jQuery is required --> 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> 


<!-- this is the plugin --> 

<script> 
    jQuery.fn.contentChange = function(callback){ 
    var elms = jQuery(this); 
    elms.each(
     function(i){ 
     var elm = jQuery(this); 
     elm.data("lastContents", elm.html()); 
     window.watchContentChange = window.watchContentChange ? window.watchContentChange : []; 
     window.watchContentChange.push({"element": elm, "callback": callback}); 
     } 
    ) 
    return elms; 
    } 
    setInterval(function(){ 
    if(window.watchContentChange){ 
     for(i in window.watchContentChange){ 
     if(window.watchContentChange[i].element.data("lastContents") != window.watchContentChange[i].element.html()){ 
      window.watchContentChange[i].callback.apply(window.watchContentChange[i].element); 
      window.watchContentChange[i].element.data("lastContents", window.watchContentChange[i].element.html()) 
     }; 
     } 
    } 
    },500); 
</script> 



<!-- some divs to test it with --> 

<p>Testing it: (click on divs to change contents)</p> 

<div id="a" onclick="$(this).append('i')">Hi</div> 
<div id="b" onclick="$(this).append('o')">Ho</div> 
<div class="c" onclick="$(this).append('y')">He</div> 
<div class="c" onclick="$(this).append('w')">He</div> 
<div class="c" onclick="$(this).append('a')">He</div> 




<!-- this is how to actually use it --> 

<script> 
    function showChange(){ 
    var element = $(this); 
    alert("it was '"+element.data("lastContents")+"' and now its '"+element.html()+"'"); 
    } 

    $('#a').contentChange(function(){ alert("Hi!") }); 
    $('div#b').contentChange(showChange); 
    $('.c').contentChange(function(){ alert("He he he...") }); 
</script> 

Tenga en cuenta que este relojes cambios en el contenido del elemento (html) solamente, no los atributos.

+2

Gracias. Claramente, la única forma de hacerlo es configurar manualmente un temporizador.Probablemente nunca necesite usar el complemento, pero felicidades por escribirlo. – ash

+0

Tenga en cuenta que esto solo observa los cambios en el contenido del elemento (html), no los atributos. –

+2

Puedes probarlo aquí: http://jsfiddle.net/KpA2C/ –

1

¿Quién/qué cambiará esto? Si se trata de un JS que controlas, úsalo para activar tu devolución de llamada. Obviamente, un usuario no puede cambiar esto.

Si desea ver un elemento <input>, etc., use el evento 'cambiar'. versión de jQuery aquí: http://api.jquery.com/change/

0

Aquí está un ejemplo de código que llama a una simple alerta cuando cambia el valor dadas:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <title>watchu, watchu, watchu want, watchu want?</title> 
</head> 
<body> 

    <div id='foo'>Hello World!</div> 

    <p><input type="button" id="ChangeButton" value="Change It" /></p> 

    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script> 
    <script type="text/javascript"> 

     $(function() { 

      $('#ChangeButton').click(function() { 
       $('#foo').html('Awfveeterzain!'); 
      }); 

      window.watchForChangeOriginalValue = $('#foo').html(); 
      watchForChange(); 
     }); 

     function watchForChange() { 
      if ($('#foo').html() != window.watchForChangeOriginalValue) 
       alert('the value changed!'); 
      else 
       window.setTimeout(watchForChange, 500); 
     } 

    </script> 
</body> 
</html> 
5

No hay un evento jQuery/DOM nativo que se active cuando cambie el contenido de HTML/DOM.

Usted puede (si se siente particularmente derrochador) hacer algo como esto:

$(function() { 
    var $div = $("#hello"); 
    var html = $div.html(); 
    var checking = setInterval(function() { 
    var newhtml = $div.html(); 
    if (html != newhtml) { 
     myCallback(); 
     html = newhtml; 
    } 
    },100); 

    function myCallback() { 
    alert('content changed!'); 
    // if you only want it to fire once, uncomment the following: 
    // clearInterval(checking); 
    } 
}); 

Sólo recuerde, llamando .html() cada 100 ms probablemente no es la mejor idea para su desempeño sitios.

jsFiddle mockup

+0

En realidad, la hay. de estos llamados [eventos de mutación] (https://developer.mozilla.org/en/XUL/Events#Mutation_DOM_events) es [slow] (http://groups.google.com/group/mozilla.dev.platform/browse_thread/thread/2f42f1d75bb906fb? pli = 1), sin embargo. –

2

Tal vez, es razonable para controlar la fuente de eventos que modifiquen el contenido de la capa (s)? Supongamos que un usuario ha hecho clic en cualquier lugar (leer, "hizo clic") después de lo que el contenido puede haber cambiado. Por lo tanto, si marca el .html() después de un clic en lugar de usar un bucle, es posible que guarde algunos recursos del sistema.

0

Hay algunos eventos llamados DOMNodeInserted, DOMNodeRemoved y DOMSubtreeModified. ¿Qué control hay elementos agregados o eliminados o cualquier Html interno modificado dentro de un div? para esto necesita una función setInterval().

function DivChange() {  
    $('#YourDiv').bind('DOMNodeInserted DOMNodeRemoved', function (event) { 
     if (event.type == 'DOMNodeInserted') { 
      alert('Content added'); 
     } else if (event.type == 'DOMNodeRemoved') { 
      alert('Content removed'); 
     } else { 
      alert('Inner Html changed for some content'); 
     } 
    }); 
} 
var DivTimer = setInterval(DivChange, 1000); 

Las funciones anteriores se comprueba el div para cualquier cambio de contenido, por cada segundo

Nota: Este evento no están soportados por el IE