Il metodo più efficace per rilevare / monitorare i cambiamenti DOM?

Ho bisogno di un meccanismo efficiente per rilevare le modifiche al DOM. Preferibilmente cross-browser, ma se ci sono mezzi efficienti che non sono cross browser, posso implementarli con un metodo cross browser fail-safe.

In particolare, ho bisogno di rilevare le modifiche che potrebbero influire sul testo di una pagina, quindi qualsiasi nuovo elemento rimosso o modificato o modifiche al testo interno (innerHTML) sarebbero necessarie.

Non ho il controllo sulle modifiche apportate (potrebbero essere dovute a javascript di terze parti inclusi, ecc.), Quindi non può essere affrontato da questo punto di vista – ho bisogno di “monitorare” le modifiche in qualche modo.

Attualmente ho implementato un metodo “quick’n’dirty” che controlla body.innerHTML.length a intervalli. Ovviamente questo non rileverà i cambiamenti che si traducono nella stessa lunghezza restituita, ma in questo caso è “abbastanza buono” – le probabilità che ciò accada sono estremamente ridotte, e in questo progetto, non riuscire a rilevare un cambiamento non risulterà nei dati persi.

Il problema con body.innerHTML.length è che è costoso. Può richiedere da 1 a 5 millisecondi su un browser veloce , e questo può rovinarsi molto – ho anche a che fare con un numero molto grande di iframe e tutto sumto. Sono abbastanza sicuro che la convenienza di fare questo è perché il testo innerHTML non è memorizzato staticamente dai browser, e deve essere calcolato dal DOM ogni volta che viene letto.

I tipi di risposte che sto cercando sono qualcosa che va dal “preciso” (ad esempio l’evento) al “abbastanza buono” – forse qualcosa come “quick’n’dirty” come il metodo innerHTML.length, ma che si esegue più velocemente.

EDIT: Vorrei anche sottolineare che mentre sarebbe “bello” rilevare l’elemento preciso che è stato modificato, non è una necessità assoluta – solo il fatto che ci sia stato qualche cambiamento sarebbe stato abbastanza buono. Spero che questo accresca le risposte della gente. Ho intenzione di indagare sugli eventi di mutazione, ma ho ancora bisogno di una soluzione alternativa per il supporto di IE, quindi qualsiasi idea sbalorditiva, creativa e fuori dagli schemi sarebbe molto gradita.

    http://www.quirksmode.org/js/events/DOMtree.html

    jQuery ora supporta un modo per albind eventi a elementi esistenti e futuri corrispondenti a un selettore: http://docs.jquery.com/Events/live#typefn

    Un’altra scoperta interessante – http://james.padolsey.com/javascript/monitoring-dom-properties/

    Per aggiornarlo, lo standard DOM4 elimina gli eventi di mutazione e li sostituisce con Mutation Observers: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

    Gli eventi di mutazione sono la raccomandazione W3 di ciò che stai cercando ..

    Non sono sicuro che siano supportati ovunque .. (IE probabilmente non li supporterà ..)

    Potresti provare a utilizzare gli eventi DOMNodeInserted e DOMNodeRemoved. Secondo Quirksmode, funzionano nella maggior parte dei browser, con la notevole eccezione di IE …

    http://www.quirksmode.org/dom/events/index.html

    Recentemente ho scritto un plugin che fa esattamente questo – jquery.initialize

    Lo usi allo stesso modo della funzione .each

     $(".some-element").initialize( function(){ $(this).css("color", "blue"); }); 

    La differenza da .each è: in questo caso, seleziona il tuo selettore e attende i nuovi elementi con questo selettore in futuro, se tale elemento verrà aggiunto verrà anch’esso inizializzato.

    Nel nostro caso, la funzione di inizializzazione cambia semplicemente il colore dell’elemento in blu. Quindi, se aggiungiamo un nuovo elemento (non importa se con ajax o persino un ispettore F12 o altro) come:

     $("
    ").addClass('some-element').appendTo("body"); //new element will have blue color!

    Il plug-in inizierà immediatamente. Inoltre il plugin si assicura che un elemento sia inizializzato solo una volta. Quindi se aggiungi un elemento, poi .deatch() dal corpo e poi lo aggiungi di nuovo, non verrà nuovamente inizializzato.

     $("
    ").addClass('some-element').appendTo("body").detach() .appendTo(".some-container"); //initialized only once

    Il plugin è basato su MutationObserver – funzionerà su IE9 e 10 con dipendenze come dettagliato nella pagina readme .

    jQuery Mutate fa anche questo, di default supporta come height, width, scrollHeight ecc … ma può anche essere esteso con un po ‘di codice in più per aggiungere nuovi eventi come vedere se il testo è cambiato ecc …

    http://www.jqui.net/jquery-projects/jquery-mutate-official/

    Spero che sia d’aiuto