2015-02-26 26 views
5

Mi capita spesso di utilizzare il seguente codice per cancellare il contenuto di un elemento:C'è un bug in Internet Explorer 9/10 con innerHTML = ""?

div.innerHTML = ""; 

ma ho trovato un comportamento Stange su Internet Explorer. Sembra che tutti i bambini del gruppo vengano rimossi anche i loro figli! Se tengo un riferimento a un figlio della divisione sopra, dopo aver eseguito div.innerHTML = "";, il nodo di testo del figlio non è più nel figlio.

Il codice seguente è la prova di questo comportamento (http://jsfiddle.net/Laudp273/):

function createText() { 
    var e = document.createElement("div"); 
    e.textContent = "Hello World!"; 
    return e; 
} 

var mrk = document.createElement("div"); 
mrk.appendChild(createText()); 
mrk.style.border = "4px solid yellow"; 

var container = null; 

function addDiv() { 
    if (container) { 
     container.innerHTML = ""; 
    } 
    var e = document.createElement("div"); 
    e.appendChild(mrk); 
    container = e; 
    document.body.appendChild(e); 
} 

var btn = document.createElement("button"); 
btn.textContent = "Add marker"; 
btn.addEventListener(
    "click", 
    function() { 
     addDiv(); 
    }, 
    false 
); 
document.body.appendChild(btn); 

Se si fa clic sul pulsante "Add Marker" due volte, si vedrà un rettangolo giallo vuoto, invece di uno con il texte " Ciao wordl! ".

Si tratta di un bug o di una specifica non utilizzata da Firefox o Google Chrome?

risposta

3

Questo comportamento è molto interessante e si verifica anche su IE8 e IE11. Ecco un piuttosto semplice test/prove:

var span = document.createElement('span'); 
 
span.appendChild(document.createTextNode("This disappears on IE")); 
 

 
var div = document.createElement('div'); 
 
div.appendChild(span); 
 
snippet.log("[before] span's childNodes.length: " + span.childNodes.length); 
 
div.innerHTML = ""; 
 
snippet.log("[after] span's childNodes.length: " + span.childNodes.length);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Dopo aver impostato s' innerHTML al "" il div, il span abbiamo mantenuto un riferimento alla perde il suo nodo di testo bambino su IE, e non su altri i browser.

We're not the only ones to notice this and find it, um, inappropriate.

Non deve essere "", sia, qualsiasi nuovo contenuto provoca l'errore:

var span = document.createElement('span'); 
 
span.appendChild(document.createTextNode("This disappears on IE")); 
 

 
var div = document.createElement('div'); 
 
div.appendChild(span); 
 
snippet.log("[before] span's childNodes.length: " + span.childNodes.length); 
 
div.innerHTML = "New content"; // <== Not "" 
 
snippet.log("[after] span's childNodes.length: " + span.childNodes.length);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

What little we have in the way of a spec for innerHTML è abbastanza vago su quello che dovrebbe accadere al vecchio contenuto, ma sicuramente questo è sbagliato, anche se Microsoft ha fatto inventare innerHTML .

Mentre la rimozione dei nodi tramite removeNode non causa questo comportamento:

var span = document.createElement('span'); 
 
span.appendChild(document.createTextNode("This disappears on IE")); 
 

 
var div = document.createElement('div'); 
 
div.appendChild(span); 
 
snippet.log("[before] span's childNodes.length: " + span.childNodes.length); 
 
while (div.firstChild) { 
 
    div.removeChild(div.firstChild); 
 
} 
 
snippet.log("[after] span's childNodes.length: " + span.childNodes.length);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

sospiro

+0

sono d'accordo. L'interpretazione di Microsoft è più che vaga. Ecco perché non uso più 'div.innerHTML =" "' Io uso 'removeChild' su ogni childnode, ma non sono sicuro che sia più veloce. – Tolokoban

+0

@Tolokoban: Lo è, in realtà, in modo drammatico. Ho una risposta da qualche parte in giro con test delle prestazioni, e (con mia grande sorpresa al momento) 'removeChild' era più veloce di impostare' innerHTML' su '" "'. * Modifica *: trovato: http://stackoverflow.com/a/13798847/157247 –

+1

La risposta collegata è già stata aggiornata. Ma per chiarire anche qui, usare 'innerHTML' è più veloce. –