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 相关文章推荐
基于jquery tab切换(防止页面刷新)
May 23 Javascript
jquery使用jquery.zclip插件复制对象的实例教程
Dec 04 Javascript
js实现同一页面多个不同运动效果的方法
Apr 10 Javascript
ionic隐藏tabs的方法
Aug 29 Javascript
JavaScript实现的CRC32函数示例
Nov 23 Javascript
使用Bootstrap打造特色进度条效果
May 02 Javascript
Vue 2中ref属性的使用方法及注意事项
Jun 12 Javascript
jquery实现倒计时小应用
Sep 19 jQuery
Vue组件的使用教程详解
Jan 05 Javascript
js统计页面上每个标签的数量实例代码
May 29 Javascript
vue中监听返回键问题
Aug 28 Javascript
浅谈vue2的$refs在vue3组合式API中的替代方法
Apr 18 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
首页四格,首页五格For6.0(GBK)(UTF-8)[12种组合][9-18][版主安装测试通过]
2007/09/24 PHP
php遍历目录方法小结
2015/03/10 PHP
php set_include_path函数设置 include_path 配置选项
2016/10/30 PHP
PHP实现的注册,登录及查询用户资料功能API接口示例
2017/06/06 PHP
jWiard 基于JQuery的强大的向导控件介绍
2011/10/28 Javascript
javascript利用控件对windows的操作实现原理与应用
2012/12/23 Javascript
js动态修改整个页面样式达到换肤效果
2014/05/23 Javascript
DIV随滚动条滚动而滚动的实现代码【推荐】
2016/04/12 Javascript
详解Angular开发中的登陆与身份验证
2016/07/27 Javascript
微信小程序登录态控制深入分析
2017/04/12 Javascript
JS实现利用两个队列表示一个栈的方法
2017/12/13 Javascript
JavaScript 中使用 Generator的方法
2017/12/29 Javascript
在AngularJs中设置请求头信息(headers)的方法及不同方法的比较
2018/09/04 Javascript
Vue实现表格中对数据进行转换、处理的方法
2018/09/06 Javascript
ES6 如何改变JS内置行为的代理与反射
2019/02/11 Javascript
微信小程序如何再次获取用户授权的方法
2019/05/10 Javascript
Vue + Elementui实现多标签页共存的方法
2019/06/12 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
2019/08/17 Javascript
vue prop属性传值与传引用示例
2019/11/13 Javascript
前端开发之便利店收银系统代码
2019/12/27 Javascript
js生成1到100的随机数最简单的实现方法
2020/02/07 Javascript
[03:02]安得倚天剑,跨海斩长鲸——中国军团出征DOTA2国际邀请赛
2018/08/14 DOTA
Python socket C/S结构的聊天室应用实现
2014/11/30 Python
django admin添加数据自动记录user到表中的实现方法
2018/01/05 Python
django组合搜索实现过程详解(附代码)
2019/08/06 Python
python程序输出无内容的解决方式
2020/04/09 Python
TensorFlow实现模型断点训练,checkpoint模型载入方式
2020/05/26 Python
Python3开发环境搭建详细教程
2020/06/18 Python
英国水族馆和池塘用品购物网站:Warehouse Aquatics
2019/08/29 全球购物
Rowdy Gentleman服装和配饰:美好时光
2019/09/24 全球购物
门卫班长岗位职责
2013/12/15 职场文书
小学三年级学生评语
2014/04/22 职场文书
总经理岗位职责说明书
2014/07/30 职场文书
基层党员对照检查材料
2014/09/24 职场文书
企业财务管理制度范本
2015/08/04 职场文书
PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库
2021/04/16 PHP