método más eficiente de detección / seguimiento de los cambios de DOM?
-
20-09-2019 - |
Pregunta
Necesito un mecanismo eficiente para la detección de cambios en el DOM. Preferentemente entre navegadores, pero si no hay ningún medio eficaz que son no navegadores, que puede poner en práctica estos con un método a prueba de fallos navegadores.
En particular, necesito para detectar cambios que afectarían el texto en una página, por lo que cualquier nuevo, eliminado o elementos, o cambios en el texto interior (innerHTML) modificado sería necesario.
No tengo control sobre los cambios que se hicieron (que podría deberse a tercera parte incluye Javascript, etc), por lo que no se puede abordar desde este punto de vista - que necesito para "monitorear" los cambios de alguna manera <. / p>
En la actualidad he implementado un método "quick'n'dirty" que comprueba body.innerHTML.length
a intervalos. Esto no va a detectar, por supuesto, que se devuelven los cambios que resultan en la misma longitud, pero en este caso es "suficientemente bueno" - las posibilidades de que esto ocurra son muy escasas, y en este proyecto, no detectar un cambio no dará lugar a la pérdida de datos.
El problema con body.innerHTML.length
es que es caro. Puede tomar entre 1 y 5 milisegundos en un rápido navegador, y esto puede atascar las cosas mucho - Yo también estoy tratando con un número grande-ish de marcos flotantes y todo suma. Estoy bastante seguro de que el elevado coste de hacer esto es porque el texto innerHTML no se almacena de forma estática por los navegadores, y necesita ser calculado a partir del DOM cada vez que se lee.
Los tipos de respuestas que estoy buscando son cualquier cosa de los "precisos" (por ejemplo evento) a la "suficientemente bueno" - tal vez algo como "quick'n'dirty" como método de innerHTML.length, pero que se ejecuta más rápido.
EDIT: También debo señalar que, si bien sería "agradable" para detectar el elemento precisa que ha sido modificado, no es una necesidad absoluta - sólo el hecho de que ha habido cualquier cambio sería lo suficientemente bueno . Espero que esto amplía las respuestas de las personas. Voy a investigar mutaciones eventos, pero todavía tengo una reserva para el apoyo de IE, por lo que cualquier, ideas creativas, fuera-de-la-plaza whacky sería muy bienvenido.
Solución
http://www.quirksmode.org/js/events/DOMtree.html
jQuery ahora es compatible con una forma de adjuntar eventos a los elementos existentes y futuros correspondientes a un selector: http: //docs.jquery.com/Events/live#typefn
Otro hallazgo interesante - http://james.padolsey.com/javascript/monitoring -dom-properties /
Otros consejos
Para llevar esto hasta la fecha, el estándar DOM4 elimina Mutación Eventos y los reemplaza con observadores Mutación: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
eventos de mutación son la recomendación W3 de lo que busca ..
No estoy seguro si son compatibles en todo .. (IE lo más probable es que no apoyarlos ..)
Se podría tratar de usar los eventos DOMNodeInserted y DOMNodeRemoved. Según Quirksmode, que tipo de trabajo en la mayoría de los navegadores, con la notable excepción del IE ...
he escrito recientemente un plugin que hace exactamente eso - jquery.initialize
Se utiliza la misma forma que la función .each
$(".some-element").initialize( function(){
$(this).css("color", "blue");
});
La diferencia de .each
es -. Le toma a su selector, en este caso .some-element
y esperar a que los nuevos elementos con este selector en el futuro, si se añade como elemento, éste se inicializará también
En nuestra función initialize caso que acabamos de cambiar de color a azul elemento. Así que si vamos a añadir nuevo elemento (no importa si con el Ajax o incluso inspector de F12 o cualquier cosa) como:
$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!
Plugin init al instante. También se asegura de plug-in, un elemento se inicia sólo una vez. Así que si se agrega el elemento y, a continuación .deatch()
desde el cuerpo y luego añadir de nuevo, no se iniciará de nuevo.
$("<div/>").addClass('some-element').appendTo("body").detach()
.appendTo(".some-container");
//initialized only once
Plugin se basa en MutationObserver
- que funcionará en IE9 y 10 con dependencias como se detalla en la página readme la .
jQuery Mutate hace esto también, por defecto se apoya como height, width, scrollHeight
etc ... pero también se puede ampliar con un poco de código adicional para añadir nuevos eventos como texto ver si ha cambiado, etc ...
http://www.jqui.net/jquery-projects/jquery -mutate-oficial /
Espero que ayuda