Ich habe einen kleinen Ärger angetroffen, der explodiert, um ein riesiges Problem zu sein.Schließen eines Fensters bricht Ereignisschleife Annahme
Problem 1: In Internet Explorer, wenn Sie ein Fenster zu schließen (die Sie über window.open
geöffnet) die ownerDocument
wird es verschwinden zusammen.
Die Folge davon ist, dass jeder Aufruf des DOM, wie appendChild
oder createElement
, mit einem SCRIPT70: Permission Denied
oder SCRIPT1717: The interface is unknown
fehl.
Ich habe mir das Verhalten anderer Browser wie Chrome angesehen. In Chrome ownerDocument
bezieht sich immer noch auf die #document
aber ownerDocument.defaultView
wird schließlich undefined
sein. Das macht für mich Sinn. Anrufe an appendChild
und createElement
werden bestehen. Ich denke, alles ist in Ordnung, solange Sie nicht versuchen, die defaultView
direkt zu verweisen.
Problem 2: In Internet Explorer, wenn Sie auf die Schließen-Schaltfläche des erstellten Fensters klicken, scheint es nicht die Ereignisschleife zu beachten. Ich habe ein unload
Ereignis an das erzeugte Fenster angehängt und es feuert sofort ab, anstatt es am Ende der Ereignisschleife einzureihen. Dies macht nicht Sinn für mich. Es ist ziemlich unmöglich, mit diesem eher trivialen Problem umzugehen.
Wenn wir hatten nur Problem 1 es würde eine Noch schmerzliche aber- einfache Lösung sein: prüfen, ob die ownerDocument
existiert und überspringen, wenn es nicht der Fall ist. Wie es ist ownerDocument
verschwindet in der Mitte der synchronen JavaScript-Code.
Erwartetes Verhalten: Ein DOM-Knoten sollte nicht verschwinden, wenn Sie darauf verwiesen haben - Garbage Collection Vernunft.
Erwartetes Verhalten 2: Ein DOM-Knoten sollte nicht im synchronen Code verschwinden. (es sei denn, du löschst es natürlich).
Bekannte Problemumgehung: Verschieben Sie den gesamten Code, der mit dem DOM interagiert, in das Fenster, sodass beim Schließen des Fensters auch die JavaScript-Laufzeitumgebung angezeigt wird. Dies ist keine triviale Lösung und erfordert möglicherweise erhebliche Änderungen in Ihrer Architektur.
Crappy Lösung: Wrap jede Funktion, die Interaktion mit dem DOM in einer Funktion, die Fehler, wenn es erkennt, das Fenster des Elements wurde geschlossen hat, macht. Dies ist ziemlich invasiv und hat erhebliche Auswirkungen auf die Leistung, und IE ist bereits so langsam.
Gibt es eine bessere Lösung?
Was ich mindestens möchte, ist ein Weg zu ignorieren alle Error
s, die geworfen werden, weil der Benutzer ein Fenster geschlossen. Problem 1 und Problem 2 brechen grundlegende Annahmen Sie über JavaScript-Code: Garbage Collection und Event-Schleife.
Demo Skript
<script type="text/javascript">
function go() {
var popup = window.open('', 'open', 'width=500,height=300,scrollbars=yes,resizable=yes');
popup.document.open();
popup.document.write('<html><head></head><body></body></html>');
popup.document.close();
for (var i = 0; i < 10000; i += 1) {
var node = popup.document.createTextNode(i + " ");
popup.document.body.appendChild(node);
}
}
</script>
<input type="button" onclick="go();" value="Open popup" />
(speichern als HTML-Datei)
Anleitung:
- Open in Internet Explorer 9
- Klicken Sie auf "Öffnen Popup"
- Schließen Sie das Fenster, während es
- beachten "Zugriff verweigert"
Hier ist es ein JSFiddle ist Rendering ist: http://jsfiddle.net/C9p2R/1/
Ist dies in allen IE-Versionen passieren? –
Es tritt in IE9 auf. Ich habe es nicht gewagt, ältere Versionen zu testen. Ich weiß nichts über IE10. – Halcyon
Verstehe ich richtig, dass Chrome das DOM geschlossener Fenster so lange ändern kann, wie Sie darauf verweisen? Und Sie wollen dieses Verhalten in IE? – Bergi