2015-02-26 9 views
5

Ich verwende oft den folgenden Code den Inhalt eines Elements zu löschen:Gibt es einen Fehler in Internet Explorer 9/10 mit innerHTML = ""?

div.innerHTML = ""; 

Aber ich seltsam Verhalten im Internet Explorer gefunden. Es scheint, dass alle Kinder des div ihre eigenen Kinder auch entfernt bekommen! Wenn ich einen Verweis auf ein Kind des obigen Bereichs beibehalten habe, nachdem div.innerHTML = ""; ausgeführt wurde, befindet sich der Textknoten des untergeordneten Elements nicht mehr im untergeordneten Element.

Der folgende Code ist der Beweis für dieses Verhalten (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); 

Wenn Sie auf die Schaltfläche „Marker hinzufügen“ Taste zweimal, werden Sie ein leeres gelbes Rechteck anstelle eines mit dem texte siehe " Hallo wordl! ".

Ist dies ein Fehler oder eine Spezifikation, die nicht von Firefox oder Google Chrome verwendet wird?

Antwort

3

Das ist sehr interessantes Verhalten und passiert auch auf IE8 und IE11. Hier ist ein ziemlich einfacher Test/Beweis:

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>

Nach dem Einstellen der div ‚s innerHTML zu "", die span wir eine Referenz gehalten verliert seine untergeordneten Textknoten auf IE, und nicht auf andere Browser.

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

Es ist nicht "", entweder sein muss, jede neue Inhalte verursacht den Fehler:

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 ist recht vage, was das geschehen soll, alter Inhalt, aber das ist sicher falsch, auch wenn Microsoft erfinden innerHTML .

Während die Knoten über removeNode Entfernen dieses Verhalten nicht verursachen:

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>

Seufzer

+0

Ich bin damit einverstanden. Die Interpretation von Microsoft ist mehr als vage. Deshalb benutze ich 'div.innerHTML =" "nicht mehr. Ich benutze 'removeChild' auf jedem childnode, aber ich bin mir nicht sicher, dass das schneller ist. – Tolokoban

+0

@Tolokoban: Es ist, tatsächlich - dramatisch. Ich habe eine Antwort irgendwo mit Leistungstests, und (zu meiner damaligen Überraschung) war 'removeChild' schneller als 'innerHTML' auf' "" zu setzen. * Bearbeiten *: Gefunden: http://stackoverflow.com/a/13798847/157247 –

+1

Die verknüpfte Antwort wurde bereits aktualisiert. Aber auch hier ist die Verwendung von 'innerHTML' schneller. –