2013-12-16 3 views
5

voglio tracciare alcuni tag speciali come componente di interfaccia utente, ad esempio <colore>, <data>, in modo che quando si crea tale elemento e inserito per DOM, posso convertirlo in . vera blocco HTML funzionaleparentNode è nullo con MutationObserver.observe (document.body

Ecco il codice, osservare addedNodes su document.body

function handleAddedNodes(nodes) { 

    [].forEach.call(nodes, function(node) { 

     if (!node.tagName) 
      return; 

     //how is it possible, node.parentNode is null????? 
     if (!node.parentNode) { 
      return; 
     } 
    }); 
} 

var observer = new MutationObserver(function(mutations) { 

    mutations.forEach(function(mutation) { 

     handleAddedNodes(mutation.addedNodes); 
    }); 
}); 

observer.observe(document.body, { 
    childList : true, 
    subtree : true 
}); 

funziona bene come previsto, ma ho anche trovato un problema strano:. nessuna parentNode per alcuni addedNodes (come "osservare (document.body "significa addedNodes dovrebbe essere discendente di document.body, giusto?)

L'intera funzione funziona come un addon per un grande progetto di frontend, non so come il progetto muta il DOM, set innerHTML o appendChild (troppo codice qui). Inoltre, non può essere sottoposto a debug, poiché la funzione di osservazione è asincrona, come evento, nessuna funzione chiamata stack.

Quindi, voglio solo sapere cosa potrebbe causare questo, e ancora meglio se può essere riprodotto con jsFiddle .

Beh, sembrava jsFiddle può riprodurre questo,

enter image description here

risposta

3

Se si aggiunge un elemento e poi subito (più veloce di quello successivo setImmediate viene attivata) rimosso ad un elemento guardato di un MutationObserver, l'osservatore notifica e aggiungi un mutation per il addedNode e lo removedNode, ma come hai notato l'elemento di riferimento non avrà un nodo genitore.

aggiornato ai esempio See fiddle

Con il MutationObserver dalla op seguente codice chiamerà handleAddedNodes tre volte, una volta per un elemento thats di stato rimosso e una volta per un elemento che è stato aggiunto all'elemento rimosso. L'elemento rimosso non avrà alcun genitore mentre il secondo elemento avrà un genitore.

var body = document.body; 
var test = document.createElement("div"); 
var test2 = document.createElement("span"); 
body.appendChild(test);//adds childList mutation (addedNodes) 
test.appendChild(test2);//adds subtree mutation (addedNodes) 
body.removeChild(test);//adds mutation (removedNodes) 
+0

Quindi come rimuovere immediatamente un elemento (più veloce del prossimo setImmediate)? – Andrew

+0

@Andrew scusa ero occupato, vedere l'aggiornamento – megawac

+0

Ok, capisco. Grazie. – Andrew