Tôi đã gặp phải một sự khó chịu nhỏ mà thổi lên là một vấn đề lớn.đóng cửa sổ phá vỡ sự kiện phá vỡ cửa sổ sự kiện
Sự cố 1: Trong Internet Explorer khi bạn đóng cửa sổ (mà bạn đã mở qua window.open
) ownerDocument
sẽ biến mất cùng với nó.
Ý nghĩa của việc này là mọi lệnh gọi đến DOM, chẳng hạn như appendChild
hoặc createElement
, sẽ không thành công với số SCRIPT70: Permission Denied
hoặc SCRIPT1717: The interface is unknown
.
Tôi đã xem xét hành vi của các trình duyệt khác như Chrome. Trong Chrome ownerDocument
vẫn tham chiếu đến #document
nhưng ownerDocument.defaultView
cuối cùng sẽ là undefined
. Điều này có ý nghĩa với tôi. Các cuộc gọi tới appendChild
và createElement
sẽ hết. Tôi nghĩ mọi thứ đều ổn, miễn là bạn không cố gắng tham khảo trực tiếp số defaultView
.
Bài 2: Trong Internet Explorer khi bạn bấm vào nút đóng của cửa sổ được sinh ra, nó dường như không tôn trọng vòng lặp Sự kiện. Tôi đã đính kèm sự kiện unload
vào cửa sổ sinh ra và nó kích hoạt ngay lập tức thay vì xếp hàng vào cuối vòng lặp Sự kiện. Điều này không không hợp lý với tôi. Nó trở thành khá không thể đối phó với vấn đề này khá tầm thường.
Nếu chúng tôi chỉ có vấn đề 1 sẽ có một giải pháp đau đớn nhưng đơn giản: kiểm tra xem ownerDocument
tồn tại và bỏ qua nếu không. Vì nó là ownerDocument
biến mất ở giữa mã JavaScript đồng bộ.
Hành vi mong đợi: nút DOM không được biến mất nếu bạn đã tham chiếu - tính năng thu thập rác thải.
Hành vi mong đợi 2: nút DOM không được biến mất trong mã đồng bộ. (trừ khi bạn xóa nó tất nhiên).
Cách giải quyết đã biết: di chuyển tất cả mã tương tác với DOM vào cửa sổ, sao cho khi cửa sổ đóng lại như vậy là môi trường chạy JavaScript. Đây không phải là một giải pháp tầm thường và có thể yêu cầu những thay đổi đáng kể trong kiến trúc của bạn.
Giải pháp crappy: bọc bất kỳ chức năng nào tương tác với DOM trong một hàm sẽ tiêu thụ lỗi nếu phát hiện cửa sổ của phần tử đã bị đóng. Điều này là khá xâm lấn và có một tác động đáng kể đến hiệu suất, và IE đã quá chậm.
Có giải pháp nào tốt hơn không?
Điều tôi muốn, ít nhất, là cách để bỏ qua bất kỳ số nào Error
s được ném vì người dùng đã đóng cửa sổ. vấn đề 1 và vấn đề 2 phá vỡ các giả định cơ bản mà bạn thực hiện về mã JavaScript: thu thập rác và vòng lặp sự kiện.
Demo kịch bản
<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" />
(save as .html tập tin)
Hướng dẫn:
- mở trong Internet Explorer 9
- Bấm "Open cửa sổ bật lên"
- Đóng cửa sổ trong khi nó render
- Quan sát "Permission Denied"
Dưới đây là một JSFiddle: http://jsfiddle.net/C9p2R/1/
Điều này có xảy ra trong tất cả các phiên bản IE không? –
Nó xảy ra trong IE9. Tôi chưa dám thử nghiệm các phiên bản cũ. Tôi không biết về IE10. – Halcyon
Tôi có hiểu rằng Chrome cho phép bạn điều chỉnh DOM của các cửa sổ đã đóng miễn là bạn giữ tham chiếu đến nó? Và bạn muốn hành vi đó trong IE? – Bergi