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中文入门指南,翻译加实例,jQuery的起点教程
Feb 09 Javascript
JavaScript Object的extend是一个常用的功能
Dec 02 Javascript
jquery 选项卡效果 新手代码
Jul 08 Javascript
《JavaScript高级程序设计》阅读笔记(二) ECMAScript中的原始类型
Feb 27 Javascript
jquery中object对象循环遍历的方法
Dec 18 Javascript
JavaScript Split()方法
Dec 18 Javascript
使用Bootstrap typeahead插件实现搜索框自动补全的方法
Jul 07 Javascript
Bootstrap整体框架之CSS12栅格系统
Dec 15 Javascript
javascript深拷贝和浅拷贝详解
Feb 14 Javascript
vue.js select下拉框绑定和取值方法
Mar 03 Javascript
vue.js的双向数据绑定Object.defineProperty方法的神奇之处
Jan 18 Javascript
ng-alain的sf如何自定义部件的流程
Jun 12 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
PHP永久登录、记住我功能实现方法和安全做法
2015/04/27 PHP
解决ThinkPHP下使用上传插件Uploadify浏览器firefox报302错误的方法
2015/12/18 PHP
初识ThinkPHP控制器
2016/04/07 PHP
PHP书写格式详解(必看)
2016/05/23 PHP
ThinkPHP模板标签eq if 中区分0,null,false的方法
2017/03/24 PHP
PHP fprintf()函数用法讲解
2019/02/16 PHP
javascript常见操作汇总
2014/09/03 Javascript
javascript学习笔记(一)基础知识
2014/09/30 Javascript
javascript 对象数组根据对象object key的值排序
2015/03/09 Javascript
js仿微博实现统计字符和本地存储功能
2015/12/22 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
2016/07/22 Javascript
IE8利用自带的setCapture和releaseCapture解决iframe的拖拽事件方法
2016/10/25 Javascript
vue.js指令v-for使用及索引获取
2016/11/03 Javascript
AngularJS extend用法详解及实例代码
2016/11/15 Javascript
BootStrap中关于Select下拉框选择触发事件及扩展
2016/11/22 Javascript
jQuery选择器实例应用
2017/01/05 Javascript
原生JS实现Ajax跨域请求flask响应内容
2017/10/24 Javascript
vue解决跨域路由冲突问题思路解析
2017/11/03 Javascript
深入浅出webpack之externals的使用
2017/12/04 Javascript
Vue通过ref父子组件拿值方法
2018/09/12 Javascript
总结javascript三元运算符知识点
2018/09/28 Javascript
vue项目打包之后背景样式丢失的解决方案
2019/01/17 Javascript
vue proxy 的优势与使用场景实现
2020/06/15 Javascript
pip matplotlib报错equired packages can not be built解决
2018/01/06 Python
利用python实现对web服务器的目录探测的方法
2019/02/26 Python
python使用KNN算法识别手写数字
2019/04/25 Python
python打开windows应用程序的实例
2019/06/28 Python
python虚拟环境的安装和配置(virtualenv,virtualenvwrapper)
2019/08/09 Python
澳大利亚在线划船、露营和钓鱼商店:BCF Australia
2020/03/22 全球购物
澳大利亚最受欢迎的女士度假服装:Kabana Shop
2020/10/10 全球购物
党支部遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
简单的个人租房协议书范本
2014/11/26 职场文书
2014年乡镇团委工作总结
2014/12/18 职场文书
2015年节能降耗工作总结
2015/05/22 职场文书
2019班干部竞选演讲稿范本!
2019/07/08 职场文书
golang中的struct操作
2021/11/11 Golang