JQuery Dialog的内存泄露问题解决方法


Posted in Javascript onJune 18, 2010

对于页面来说,JQuery中的Dialog从效果上来说还可以,而且使用简单,只要短短几行绑定的代码就可以实现弹出效果。
代码

$('#dialog').dialog({ 
autoOpen: false, 
width: 600, 
buttons: { 
"Ok": function() { 
$(this).dialog("close"); 
}, 
"Cancel": function() { 
$(this).dialog("close"); 
} 
} 
});

在一些JS交互性不多的一般页面来说,没有任何问题!但是对于交互性强的,需要动态加载与释放DOM的页面来说,它就是一个悲剧的东西!为什么这样说?大家看下下面的例子:

一段简单的代码,一个DIV是通过动态加载到页面上,然后对该DIV用Dialog进行绑定,以达到弹出的目的!下面的test元素就是<div id="test"></div>。
代码

function TestAppend() { 
$("#test").append('<div id="dialog"><div id="fileQueue"></div> <input type="file" name="uploadify" id="uploadify" />' + 
'<a href="javascript:upload();">上传</a>' + 
'<a href="javascript:$(#uploadify).uploadifyClearQueue()">取消上传</a><div>'); 
$('#dialog').dialog({ 
autoOpen: false, 
width: 600, 
buttons: { 
"Ok": function() { 
$(this).dialog("close"); 
}, 
"Cancel": function() { 
$(this).dialog("close"); 
} 
} 
}); 
return false; 
}

接着,我需要删除该DOM元素,一般来说,正常的做法都是$("#test").empty();这行简单的代码就完成了!这样有效吗?!当执行完这样代码后,你再用$('#dialog')来获取dialog元素,郁闷的事情发生了,既然获取到了!为什么!不是已经empty了吗!

下面我们来看下这一悲剧是如何造成的,

我们把注意点放到$('#dialog').dialog上面,然后看看JQuery的实现代码是如何写的,当我们跟踪代码到dialog类中的_create方法的时候,问题的原因找到了,看下面这段代码:

uiDialog = (self.uiDialog = $('<div></div>')) 
.appendTo(document.body) 
.hide() 
.addClass(uiDialogClasses + options.dialogClass) 
.css({ 
zIndex: options.zIndex 
}) 
// setting tabIndex makes the div focusable 
// setting outline to 0 prevents a border on focus in Mozilla 
.attr('tabIndex', -1).css('outline', 0).keydown(function(event) { 
if (options.closeOnEscape && event.keyCode && 
event.keyCode === $.ui.keyCode.ESCAPE) { 
self.close(event); 
event.preventDefault(); 
} 
}) 
.attr({ 
role: 'dialog', 
'aria-labelledby': titleId 
}) 
.mousedown(function(event) { 
self.moveToTop(false, event); 
}),

它既然也动态创建一个div,而且把该div加到了Body上面,然后把dialog中的元素从<div id=test>中移除,加入到该新的div中.....

这就是为什么我们$("#test").empty()后,却对内部的dialog没有起作用了!而且这有一个最不好的一个地方,也是最容易出现内存泄露的地方:它动态的在Body中创建了一个div,这样如果窗体不关闭的话,而你又在不察觉的情况下不断的使用上面的TestAppend方法来动态加载DOM,就会创建N个这样的div!

其实这个问题郁闷的地方不是在如何解决,而且隐藏的很深,很难发现!那么发现之后解决起来就变的简单多了:

if ($('#dialog')[0]) { 
$('#dialog').parent().empty(); 
$('#dialog').parent().remove(); 
}

当前加上这段后代码后,再做$("#dialog")来测试下,期望的结果终于出现了!dialog元素消失了!
Javascript 相关文章推荐
JS 遮照层实现代码
Mar 31 Javascript
Jquery+CSS3实现一款简洁大气带滑动效果的弹出层
May 15 Javascript
jquery实现图片滚动效果的简单实例
Nov 23 Javascript
js获取select标签的值且兼容IE与firefox
Dec 30 Javascript
jQuery简单实现禁用右键菜单
Mar 10 Javascript
js实现字符串转日期格式的方法
May 20 Javascript
js实现获取两个日期之间所有日期的方法
Jun 17 Javascript
jquery删除table当前行的实例代码
Oct 07 Javascript
w3c编程挑战_初级脚本算法实战篇
Jun 23 Javascript
js实现同一个页面,多个enter事件绑定的示例
Oct 10 Javascript
jQuery实现的鼠标拖动浮层功能示例【拖动div等任何标签】
Dec 29 jQuery
对vuex中store和$store的区别说明
Jul 24 Javascript
通过jQuery打造支持汉字,拼音,英文快速定位查询的超级select插件
Jun 18 #Javascript
jquery ready()的几种实现方法小结
Jun 18 #Javascript
JQuery在光标位置插入内容的实现代码
Jun 18 #Javascript
JavaScript Chart 插件整理
Jun 18 #Javascript
JavaScript在IE和Firefox浏览器下的7个差异兼容写法小结
Jun 18 #Javascript
Javascript下IE与Firefox下的差异兼容写法总结
Jun 18 #Javascript
js打印纸函数代码(递归)
Jun 18 #Javascript
You might like
日本收入最高的漫画家:海贼王作者版税年收入高达8.45亿元
2020/03/04 日漫
WindowsXP中快速配置Apache+PHP5+Mysql
2008/06/05 PHP
Django中的cookie与session操作实例代码
2017/08/17 PHP
显示、隐藏密码
2006/07/01 Javascript
FireFox与IE 下js兼容触发click事件的代码
2008/11/20 Javascript
javascript 动态修改样式和层叠样式表代码
2010/04/27 Javascript
JavaScript采用递归算法计算阶乘实例
2015/08/04 Javascript
浏览器复制插件zeroclipboard使用指南
2016/03/26 Javascript
基于javascript实现数字英文验证码
2017/01/25 Javascript
Angular 4 指令快速入门教程
2017/06/07 Javascript
bootstrap轮播模板使用方法详解
2017/11/17 Javascript
node.js中axios使用心得总结
2017/11/29 Javascript
利用jquery如何从json中读取数据追加到html中
2017/12/01 jQuery
教你30秒发布一个TypeScript包到NPM的方法步骤
2019/07/22 Javascript
JS document form表单元素操作完整示例
2020/01/13 Javascript
JavaScript中的this妙用实例分析
2020/05/09 Javascript
Python中捕捉详细异常信息的代码示例
2014/09/18 Python
python中偏函数partial用法实例分析
2015/07/08 Python
python:socket传输大文件示例
2017/01/18 Python
python中对数据进行各种排序的方法
2019/07/02 Python
微信小程序python用户认证的实现
2019/07/29 Python
使用浏览器访问python写的服务器程序
2019/10/10 Python
利用Python代码实现一键抠背景功能
2019/12/29 Python
如何通过python检查文件是否被占用
2020/12/18 Python
英国邮购活的植物主要供应商:Gardening Direct
2019/01/28 全球购物
攀岩、滑雪、徒步旅行装备:Black Diamond Equipment
2019/08/16 全球购物
美国室内盆栽植物购买网站:Plants.com
2020/04/24 全球购物
竞选大队长演讲稿
2014/04/29 职场文书
2015年消防工作总结
2015/04/24 职场文书
导游词之山西-五老峰
2019/10/07 职场文书
关于vue中如何监听数组变化
2021/04/28 Vue.js
使用redis实现延迟通知功能(Redis过期键通知)
2021/09/04 Redis
JS 4个超级实用的小技巧 提升开发效率
2021/10/05 Javascript
Python实现视频中添加音频工具详解
2021/12/06 Python
MySQL学习之基础操作总结
2022/03/19 MySQL
js判断两个数组相等的5种方法
2022/05/06 Javascript