IE浏览器IFrame对象内存不释放问题解决方法,II
分类:美高梅游戏官网网站

最近项目组发现在使用showModalDialog弹出窗体中如果包含IFrame对象,则IFrame对象占用的内存资源在窗体关闭后不会释放。弹出关闭反复多次后,IE浏览器内存占用可超过数百M,严重时IE浏览器报错,且无法关闭,只能通过杀进程的方式重启浏览器。经测试,使用open方式弹出也存在该问题。

IE浏览器IFrame对象内存不释放问题解决方法,ieiframe

最近项目组发现在使用showModalDialog弹出窗体中如果包含IFrame对象,则IFrame对象占用的内存资源在窗体关闭后不会释放。弹出关闭反复多次后,IE浏览器内存占用可超过数百M,严重时IE浏览器报错,且无法关闭,只能通过杀进程的方式重启浏览器。经测试,使用open方式弹出也存在该问题。

在IE8浏览器中,open和showModalDialog弹出的内存占用有差异:

open方式弹出的窗体占用的是一个独立的iexplorer.exe进程;

showModalDialog方式弹出的窗体使用和父窗体相同的iexplorer.exe进程;

经过搜索,发现解决办法是在窗体关闭前,从窗体中删除IFrame对象,代码如下:

var el = document.getElementById("scanIf");
el.src="";
el.contentWindow.document.write('');
el.contentWindow.document.clear();
var p = el.parentNode;
p.removeChild(el);

但是测试的时候,发现有两个限制:

1. el.src可能还没有执行完,就执行后面的语句,如果IFrame中包含的是跨域内容,则会提示没有权限;

  1. 窗体关闭的比脚本执行的快,内存仍然没有释放;

经过修改,最终脚本如下:

<!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>

What?模态对话框失效了?

      公司开发的网站使用的.net,网站中用到了定时器,放在Global.asax.cs文件中,但由于IIS设置了网站进程定期回收,回收后定时器也就没了。如果不让进程回收,又担心程序中有内存泄露。有人说可以在Application_End发起HTTP请求,但这样做和设置不让进程回收没有任何区别,结果就是该进程一直运行,只有保证不存在内存泄露才可以这样做。也有人说可以用Windows Service,对这个不了解,所以这招放弃了。最后想到了一个方法,编写脚本命令(这里用DOS命令)访问网站,再通过Windows的任务计划来定时执行脚本。.bat文件如下,直接运行该.bat,发现会用IE浏览器打开www.baidu.com,几秒后关闭,看来命令运行是OK的。

在IE8浏览器中,open和showModalDialog弹出的内存占用有差异:

对于iframe 关闭后,IE下不可以释放内存的问题,跪解决方案

美高梅网址,如果你的iframe的内容里面有flash,那就不一定是iframe的问题了

一般:cif.parentNode.removeChild(cif); 就能解决问题的  

上个礼拜修改测试一个后台管理项目,在测试与各个浏览器兼容性的时候,发现在chrome浏览器下showModalDialog方法显示的并不是模态对话框,就像新打开一个页面一样,父窗口仍然可以随意获取焦点,并可以打开多个窗体,而且返回值returnValue也无法返回,一直是undefined。这么多问题很令人头疼,下面就各个主流最新版的浏览器进行了一下测试。

                                    ::访问网站,触发定时器
                                    ::ping10次后关闭,10次大约延时10秒左右,不是很精确,然后关闭IE浏览器进程及子进程
                                     start iexplore.exe  www.baidu.com ::为了保密,这里没写真正要访问的网站
                                     ping -n 10 127.0.0.1>nul
                                     taskkill /f /im iexplore.exe  /t

open方式弹出的窗体占用的是一个独立的iexplorer.exe进程;

某一网页显示该浏览器不支持iframe,该怎办??

不会啊!IE支持Iframe啊!是不是浏览器设置问题!  

最近项目组发现在使用showModalDialog弹出窗体中如果包含IFrame对象,则IFrame对象占用的内...

浏览器 是否支持 状态
IE9
Firefox13.0
safari5.1
chrome19.0 × 并不是模态对话框,而是open了一个新窗体
Opera12.0 × 什么也发生,连个窗体都不弹

      任务计划在附件——系统工具中,可以“创建基本任务”和“创建任务”,前者比较简单,定时器的最短间隔为1天,后者功能更强大一些,定时器的最短间隔为1分钟。这里我使用“创建任务”,在“常规”中可以设置“只在用户登当运行”或“不管用户是否登录都要运行”,这里设置“不管用户是否登录都要运行”(注:选择该项时,设置完所有参数后会要求输入账户密码,如果账户密码为空,会提示错误,但貌似空密码也有解决办法),配置选与自己电脑的匹配的那项。建立好任务后,当定时器时间到了却没有打开IE浏览器的窗口,再看任务管理器,有进程iexplore.exe,而且网站也的确被访问了(在计划任务运行之前,网站进程是关闭的,而且可以保证该段时间内没有人访问,现在发现网站进程运行中),经过多次设置参数和测试,结果依旧。但如果设置成“只在用户登当运行”,却可以看到定时器到后会打开IE窗口。后来在CSDN看到一个帖子

showModalDialog方式弹出的窗体使用和父窗体相同的iexplorer.exe进程;

Chrome到底打开的是什么

缺点:

经过搜索,发现解决办法是在窗体关闭前,从窗体中删除IFrame对象,代码如下:

因为打开的不是模态对话框,而是像open了一个新窗体一样,那只要验证一下子窗体window.opener是否为空就明白了。

      1、任务计划的定时器最短间隔为1分钟,如果再短的,就无能为力了,其实即使可以,也不要用这种发HTTP请求的方法去激活网站进程,之前设置每5秒发一次HTTP请求,最后服务器挂了,只能重启,原因也没查出来(后来知道不是因为HTTP请求频繁导致的,至于HTTP请求频繁会不会导致死机,我不清楚。通过事件日志,发现本次死机是因为Windows自动更新后重启,电脑是3点多开始重启的,但到9点了还没起来,后打电话问万网的客服,他们说电脑还在关机界面,看来应该是自动更新的问题。让他们重启后,就OK了,然后禁用了自动更新)。

var el = document.getElementById("scanIf");
el.src="";
el.contentWindow.document.write('');
el.contentWindow.document.clear();
var p = el.parentNode;
p.removeChild(el);
<script type="text/javascript">
    alert(window.opener);
</script>

      2、关闭IE就意味着关闭所有页面,如果我们这时正在用IE看其它网页,那也会关闭,不过还好,因为是在服务器上,一般没人打开IE。

但是测试的时候,发现有两个限制:

在chrome中,显示的是一个[object window]对象,而IE则是undefined。现在知道原来chrome将showModalDialog当作window.open来处理了。也就是说我们完全可以用window.opener来操作chrome浏览器下子窗体。这里还发现个很有趣的现象,firefox中测试window.opener也并不为空,于是我又测试了下使用showModalDialog在子窗体中关于window.opener和window.dialogArguments在各个浏览器里的状况,由于Opera浏览器连个窗体都不弹,下面测试就剔除它了。

1. el.src可能还没有执行完,就执行后面的语句,如果IFrame中包含的是跨域内容,则会提示没有权限;

说明下父窗体的showModalDialog的方法中arguments传递是window对象,下面是测试的结果:

  1. 窗体关闭的比脚本执行的快,内存仍然没有释放;
浏览器 模态对话框 window.opener window.dialogArguments returnValue
IE9 undefined [object Window]
Firefox13.0 [object Window] [object Window]
safari5.1 [object Window] [object Window]
chrome19.0 × [object Window] undefined ×

经过修改,最终脚本如下:

以上是我测试的结果,各个浏览器所支持的程度还是不一样的。还要说一下Firefox浏览器下,子窗体假如刷新的话window.dialogArguments照样会丢失,变成undefined。以上结果中我们可以看出返回值returnValue就只有chrome浏览器返回的是undefined,其他浏览器都没有问题。那该如何解决这个问题呢?

<!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>

解决returnValue问题

您可能感兴趣的文章:

  • JQuery1.4+ Ajax IE8 内存泄漏问题
  • iframe如何动态创建及释放其所占内存
  • IE8 内存泄露(内存一直增长 )的原因及解决办法

通过以上的种种测试,我们已经知道chrome的showModalDialog方法很像执行了window.open方法,那么我们可以利用window.opener来实现window.returnValue的功能。

注意:temp=Math.random()这个随机参数是为了解决缓存问题,不少朋友测试出undefined是因为是缓存的问题。 追加于2012-10-17

父窗体部分js代码:

window.onload = function () {
  var returnValue = window.showModalDialog("son.html?temp=" + Math.random(), window);
  //for chrome
  if (returnValue == undefined) {
    returnValue = window.returnValue;
  }

  alert(returnValue);
}

子窗体部分js代码:

if (window.opener != undefined) {
    //for chrome
    window.opener.returnValue = "opener returnValue";
}
else {
    window.returnValue = "window returnValue";
}
window.close();

这样也在IE,FireFox,Chrome,Safari等浏览器下都可以通用了。

最后

最后有人要问那该如何实现模态对话框呢?我觉得应该是可以用一些js技巧去实现的,但是我不并推荐这样做,我也查询了很资料都不能很好的解决这个问题。当然,也可以有其他一些思路,比如为了不弹出更多的窗体,可以在点击打开窗体的时候将那个open按钮设置为不可用,只有关闭了子窗体再设置成可用。这些大家都可以自己去实践下,或许有更好的方法。

最后我想说的是在当今的网页设计中很流行用div在页面内去模拟一个窗体,样式自定义,交互都很不错,不一定非要用模态窗体,如何模拟网上一大把,今天就写到这里吧,有什么错误的地方请大家多指正~~

您可能感兴趣的文章:

  • js模式化窗口问题![window.dialogArguments]
  • window.dialogArguments 使用说明
  • JS在Chrome浏览器中showModalDialog函数返回值为undefined的解决方法
  • 谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
  • 谷歌浏览器不支持showModalDialog模态对话框的解决方法
  • showModalDialog模态对话框的使用详解以及浏览器兼容
  • showModalDialog在谷歌浏览器下会返回Null的解决方法
  • window.showModalDialog两次加载问题清除缓存方法
  • Chrome中模态对话框showModalDialog返回值问题的解决方法

本文由美高梅网址发布于美高梅游戏官网网站,转载请注明出处:IE浏览器IFrame对象内存不释放问题解决方法,II

上一篇:来判断获取的tagName,jquery获取tagName再进行判断 下一篇:JS不能跨域借助jquery获取IP地址的方法,javascrip
猜你喜欢
热门排行
精彩图文