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 相关文章推荐
mysql输出数据赋给js变量报unterminated string literal错误原因
May 22 Javascript
js jquery数组介绍
Jul 15 Javascript
JavaScript中创建类/对象的几种方法总结
Nov 29 Javascript
parentElement,srcElement的使用小结
Jan 13 Javascript
jQuery遍历DOM元素与节点方法详解
Apr 14 Javascript
ReactJS实现表单的单选多选和反选的示例
Oct 13 Javascript
react实现点击选中的li高亮的示例代码
May 24 Javascript
vue中使用sessionStorage记住密码功能
Jul 24 Javascript
JS+php后台实现文件上传功能详解
Mar 02 Javascript
在小程序中推送模板消息的实现方法
Jul 22 Javascript
vue中使用极验验证码的方法(附demo)
Dec 04 Javascript
vue中封装axios并实现api接口的统一管理
Dec 25 Vue.js
通过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
php计算函数执行时间的方法
2015/03/20 PHP
关于PHP通用返回值设置方法
2017/03/31 PHP
微信公众平台开发教程①获取用户Openid及个人信息图文详解
2019/04/10 PHP
Javascript的IE和Firefox兼容性汇编
2006/07/01 Javascript
window.open的功能全解析
2006/10/10 Javascript
一个封装js代码-----展开收起效果示例
2013/07/03 Javascript
javascript闭包的高级使用方法实例
2013/07/04 Javascript
固定表格行列(expression)在IE下适用
2013/07/25 Javascript
使用javascript控制cookie显示和隐藏背景图
2014/02/12 Javascript
基于Node.js实现nodemailer邮件发送
2016/01/26 Javascript
jquery表单验证插件formValidator使用方法
2016/04/01 Javascript
JavaScript中各种引用类型的常用操作方法小结
2016/05/05 Javascript
原生JS实现风箱式demo,并封装了一个运动框架(实例代码)
2016/07/22 Javascript
详解用原生JavaScript实现jQuery的某些简单功能
2016/12/19 Javascript
vue 父组件调用子组件方法及事件
2018/03/29 Javascript
如何使用puppet替换文件中的string
2018/12/06 Javascript
vuex存值与取值的实例
2019/11/06 Javascript
vue-cli3 引入 font-awesome的操作
2020/08/11 Javascript
python自动化工具日志查询分析脚本代码实现
2013/11/26 Python
Python中音频处理库pydub的使用教程
2017/06/07 Python
python3爬取各类天气信息
2018/02/24 Python
python清除字符串中间空格的实例讲解
2018/05/11 Python
python openCV获取人脸部分并存储功能
2019/08/28 Python
django 取消csrf限制的实例
2020/03/13 Python
css3绘制百度的小度熊
2018/10/29 HTML / CSS
CSS3实现翘边的阴影效果的代码示例
2016/06/13 HTML / CSS
Tod’s英国官方网站:意大利奢华手工制作手袋和鞋履
2019/03/15 全球购物
工商管理本科毕业生求职信范文
2013/10/05 职场文书
自我鉴定书
2014/03/24 职场文书
2014年六一儿童节演讲稿
2014/05/23 职场文书
本科毕业生应聘自荐信范文
2014/06/26 职场文书
小学生安全教育主题班会
2015/08/12 职场文书
tensorflow学习笔记之tfrecord文件的生成与读取
2021/03/31 Python
MYSQL 的10大经典优化案例场景实战
2021/09/14 MySQL
基于Redis结合SpringBoot的秒杀案例详解
2021/10/05 Redis
vue使用element-ui按需引入
2022/05/20 Vue.js