最近项目组发现在使用showModalDialog弹出窗体中如果包含IFrame对象,则IFrame对象占用的内存资源在窗体关闭后不会释放。弹出关闭反复多次后,IE浏览器内存占用可超过数百M,严重时IE浏览器报错,且无法关闭,只能通过杀进程的方式重启浏览器。经测试,使用open方式弹出也存在该问题。
在IE8浏览器中,open和showModalDialog弹出的内存占用有差异:
open方式弹出的窗体占用的是一个独立的iexplorer.exe进程;
showModalDialog方式弹出的窗体使用和父窗体相同的iexplorer.exe进程;
经过搜索,发现解决办法是在窗体关闭前,从窗体中删除IFrame对象,代码如下:
1
2
3
4
5
6
7
8
|
<span style= "font-size:18px" > var el = document.getElementById( "scanIf" ); el.src= "" ; el.contentWindow.document.write( '' ); el.contentWindow.document.clear(); var p = el.parentNode; p.removeChild(el); </span> |
但是测试的时候,发现有两个限制:
1. el.src可能还没有执行完,就执行后面的语句,如果IFrame中包含的是跨域内容,则会提示没有权限;
2. 窗体关闭的比脚本执行的快,内存仍然没有释放;
经过修改,最终脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML><HEAD><TITLE></TITLE> <BODY onbeforeunload= "return unloadHandler();" > <IFRAME id= "scanIf" width= "800px" height= "600px" src = "http://www.baidu.com" ></IFRAME> <SCRIPT type= "text/javascript" > function unloadHandler(notip) { // 取消窗口关闭时的监听事件 document.getElementsByTagName( "BODY" )[0].onbeforeunload = null ; var el = document.getElementById( "scanIf" ); if (el) { el.src = "" ; setTimeout(cycleClear, 100); return "提示:请点击取消按钮,当前窗口会自动关闭。" ; } return true ; } function cycleClear() { try { var el = document.getElementById( "scanIf" ); if (el) { el.contentWindow.document.write( '' ); el.contentWindow.document.clear(); var p = el.parentNode; p.removeChild(el); } window.close(); } catch (e) { setTimeout(cycleClear, 100); } } //window.onunload = unloadHandler; </SCRIPT> <input type= "button" value= "remove" onclick= "unloadHandler();" > </BODY></HTML> |