two div all javascript jquery google-chrome-extension

div - ¿Hay un detector de cambios de JavaScript/jQuery DOM?



wrap all elements in div jquery (5)

Además de las herramientas "en bruto" proporcionadas por la docs , existen bibliotecas de "conveniencia" para trabajar con mutaciones DOM.

Considere: MutationObserver representa cada cambio de DOM en términos de subárboles. Por lo tanto, si, por ejemplo, está esperando que se inserte un elemento determinado, es posible que se encuentre dentro de los hijos de mutations.mutation[i].addedNodes[j] .

Otro problema es cuando su propio código, en respuesta a las mutaciones, cambia el DOM: a menudo desea filtrarlo.

Una buena biblioteca de conveniencia que resuelve tales problemas es mutation-summary (exención de responsabilidad: no soy el autor, solo soy un usuario satisfecho), que le permite especificar consultas sobre lo que le interesa y obtener exactamente eso.

Ejemplo de uso básico de la documentación:

var observer = new MutationSummary({ callback: updateWidgets, queries: [{ element: ''[data-widget]'' }] }); function updateWidgets(summaries) { var widgetSummary = summaries[0]; widgetSummary.added.forEach(buildNewWidget); widgetSummary.removed.forEach(cleanupExistingWidget); }

Esencialmente quiero que se ejecute un script cuando cambien los contenidos de un DIV. Dado que los scripts son independientes (script de contenido en extensión de chrome y script de página web), necesito una manera de simplemente observar los cambios en el estado DOM Podría configurar el sondeo, pero eso parece descuidado.


Muchos sitios usan AJAX para agregar / mostrar / cambiar contenido dinámicamente. A veces se usa en lugar de la navegación en el sitio, por lo que la URL actual se cambia mediante programación y los scripts de contenido no se ejecutan automáticamente por el navegador en este caso, ya que la página no se recupera completamente del servidor remoto.

Métodos habituales de JS para detectar cambios de página disponibles en un script de contenido .

  • MutationObserver ( docs ) para detectar literalmente cambios en el DOM:

    • Cómo cambiar el contenido HTML a medida que se carga en la página
    • Rendimiento de MutationObserver para detectar nodos en todo el DOM .
  • Detector de eventos para sitios que indican cambios en el contenido al enviar un evento DOM:

    • pjax:end en el document utilizado por muchos sitios basados ​​en pjax, por ejemplo, GitHub,
      Consulte ¿Cómo ejecutar jQuery antes y después de una carga pjax?
    • message en la window utilizado por ejemplo, la búsqueda de Google en el navegador Chrome,
      ver la extensión de Chrome detectar actualización de búsqueda de Google
    • spfdone en el document utilizado por Youtube,
      Consulte ¿Cómo detectar la navegación de la página en Youtube y modificar HTML antes de que se represente la página?
  • Comprobación periódica de DOM a través de setInterval :
    Obviamente, esto funcionará solo en los casos en que espere a que aparezca un elemento específico identificado por su id / selector, y no le permitirá detectar universalmente nuevo contenido agregado dinámicamente a menos que invente algún tipo de huella dactilar del contenido existente.

  • Encubriendo la API de historial dentro de un script DOM inyectado :

    document.head.appendChild(document.createElement(''script'')).text = ''('' + function() { // injected DOM script is not a content script anymore, // it can modify objects and functions of the page var _pushState = history.pushState; history.pushState = function(state, title, url) { _pushState.call(this, state, title, url); window.dispatchEvent(new CustomEvent(''state-changed'', {detail: state})); }; // repeat the above for replaceState too } + '')(); this.remove();''; // remove the DOM script element // And here content script listens to our DOM script custom events window.addEventListener(''state-changed'', function(e) { console.log(''History state changed'', e.detail, location.hash); doSomething(); });

  • Escuchando hashchange , popstate eventos:

    window.addEventListener(''hashchange'', function(e) { console.log(''URL hash changed'', e); doSomething(); }); window.addEventListener(''popstate'', function(e) { console.log(''State changed'', e); doSomething(); });


Extensiones específicas: detecta cambios de URL en una página de background / evento .

Existe una API avanzada para trabajar con la navegación: webNavigation , webRequest , pero usaremos chrome.tabs.onUpdated , un detector de eventos chrome.tabs.onUpdated que envía un mensaje al script de contenido:

  • manifest.json:
    declarar página de fondo / evento
    declarar contenido script
    Añadir permission "tabs" .

  • background.js

    var rxLookfor = /^https?:////(www/.)?google/.(com|/w/w(/./w/w)?)//.*?[?#&]q=/; chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { if (rxLookfor.test(changeInfo.url)) { chrome.tabs.sendMessage(tabId, ''url-update''); } });

  • content.js

    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) { if (msg === ''url-update'') { doSomething(); } });


Otro enfoque dependiendo de cómo estás cambiando el div. Si está utilizando JQuery para cambiar el contenido de un div con su método html (), puede extender ese método y llamar a una función de registro cada vez que ponga html en un div.

(function( $, oldHtmlMethod ){ // Override the core html method in the jQuery object. $.fn.html = function(){ // Execute the original HTML method using the // augmented arguments collection. var results = oldHtmlMethod.apply( this, arguments ); com.invisibility.elements.findAndRegisterElements(this); return results; }; })( jQuery, jQuery.fn.html );

Simplemente interceptamos las llamadas a html (), llamamos a una función de registro con esto, que en el contexto se refiere al elemento de destino que obtiene contenido nuevo, luego pasamos la llamada a la función jquery.html () original. Recuerde devolver los resultados del método html () original, porque JQuery lo espera para el encadenamiento de métodos.

Para obtener más información sobre la anulación y extensión de métodos, visite http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm , que es donde Cribbed la función de cierre. También puedes ver el tutorial de complementos en el sitio de JQuery.


Editar

Esta respuesta ahora está en desuso. Vea la respuesta por apsillers .

Dado que esto es para una extensión de Chrome, también puede utilizar el evento DOM estándar: DOMSubtreeModified . Vea el soporte para este event todos los navegadores. Se ha soportado en Chrome desde 1.0.

$("#someDiv").bind("DOMSubtreeModified", function() { alert("tree changed"); });

Vea un ejemplo de trabajo here .


Varios años después, ahora hay oficialmente una mejor solución. Los observadores de mutación DOM4 son el reemplazo para los eventos de mutación DOM3 obsoletos. Actualmente se implementan en navegadores modernos como MutationObserver (o como WebKitMutationObserver prefijo del WebKitMutationObserver en versiones anteriores de Chrome):

MutationObserver = window.MutationObserver || window.WebKitMutationObserver; var observer = new MutationObserver(function(mutations, observer) { // fired when a mutation occurs console.log(mutations, observer); // ... }); // define what element should be observed by the observer // and what types of mutations trigger the callback observer.observe(document, { subtree: true, attributes: true //... });

Este ejemplo escucha los cambios de DOM en el document y su subárbol completo, y activará los cambios en los atributos del elemento, así como los cambios estructurales. El borrador de la especificación tiene una lista completa de propiedades válidas de escucha de mutación :

lista de niños

  • Se establece en true si se deben observar mutaciones en los hijos del objetivo.

atributos

  • Se establece en true si se deben observar mutaciones en los atributos del objetivo.

caracterDatos

  • Se establece en true si se deben observar mutaciones en los datos del objetivo.

subárbol

  • Se establece en true si se deben observar las mutaciones no solo del objetivo, sino también de los descendientes del objetivo.

attributeOldValue

  • Establézcalo en true si los attributes se configuran en verdadero y el valor del atributo del objetivo antes de que la mutación deba registrarse.

characterDataOldValue

  • Establézcalo en true si characterData se establece en verdadero y los datos del objetivo antes de que se registre la mutación.

atributoFiltro

  • Establezca una lista de nombres de atributos locales (sin espacio de nombres) si no es necesario observar todas las mutaciones de los atributos.

(Esta lista está actualizada a partir de abril de 2014; puede consultar la especificación de cualquier cambio).