Я столкнулся с небольшой досадой, которая взрывается, чтобы быть огромной проблемой.
Проблема 1: В обозревателе Internet Explorer при закрытии окна (которое вы открыли через window.open
), ownerDocument
исчезнет вместе с ним.
Следствием этого является то, что любой вызов DOM, такой как appendChild
или createElement
, потерпит неудачу с помощью SCRIPT70: Permission Denied
или SCRIPT1717: The interface is unknown
.
Я посмотрел на поведение других браузеров, таких как Chrome. В Chrome ownerDocument
все еще ссылаются на #document
, но ownerDocument.defaultView
в конечном итоге будет undefined
. Это имеет смысл для меня. Вызовы appendChild
и createElement
пройдут. Я думаю, что все в порядке, пока вы не пытаетесь напрямую ссылаться на defaultView
.
Проблема 2: В Internet Explorer, когда вы нажимаете кнопку закрытия закрытого окна, похоже, что это не соответствует циклу Event. Я приложил событие unload
к порожденному окну, и он немедленно запускается, а не ставит его в очередь в конце цикла Event. Для меня это не имеет смысла. Совершенно невозможно справиться с этой довольно тривиальной проблемой.
Если бы у нас была проблема 1, было бы болезненное, но простое решение: проверьте, существует ли ownerDocument
и пропустите, если это не так. Поскольку ownerDocument
исчезает в середине синхронного кода JavaScript.
Ожидаемое поведение: DOM node не должен исчезать, если вы ссылаетесь на него - разумность сборки мусора.
Ожидаемое поведение 2: DOM node не должно исчезать в синхронном коде. (если вы не удалите его, конечно).
Известное обходное решение: переместите весь код, который взаимодействует с DOM в окне, так что, когда окно закрыто, это среда выполнения JavaScript. Это не тривиальное решение и может потребовать значительных изменений в вашей архитектуре.
Решение Crappy: завершает любую функцию, которая взаимодействует с DOM в функции, которая будет потреблять ошибки, если обнаруживает, что окно элемента закрыто. Это довольно инвазивное и оказывает значительное влияние на производительность, и IE уже настолько медленный.
Есть ли лучшее решение?
То, что я хочу, по крайней мере, является способом игнорировать любой Error
, который вызывается, потому что пользователь закрыл окно. проблема 1 и проблема 2 нарушают основные предположения, которые вы делаете о JavaScript-коде: сбор мусора и цикл событий.
Демо script
<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" />
(сохранить как .html файл)
Инструкция:
- Открыть в Internet Explorer 9
- Нажмите "Открыть всплывающее окно"
- Закройте окно при его рендеринге
- Наблюдайте за разрешением "Отказано"
Здесь это JSFiddle: http://jsfiddle.net/C9p2R/1/