jQuery移除元素自动解绑事件实现思路及代码


Posted in Javascript onMay 31, 2014

世界本该如此!

所以,在现代浏览器,如果你将一个元素从DOM树种进行移除的时候,浏览器会自动帮你绑定的事件进行解绑以释放其占用的内存。也许你猜到了,较老版本的浏览器则不会主动去做这件事,所以,当你的应用在较老版本的浏览器运行的越久,其消耗内存越多,应用就会变得越来越卡。因此,需要我们自己对要删除的元素进行事件解绑。

实现思路

用jQuery将元素移除的基本方法常用的有三个,一个是remove()方法,一个是html()方法,一个是empty()方法。我们可以对此三个方法进行进一步的封装,我们会在事件绑定的时候给绑定事件的元素添加一个属性标识,从要删除的元素中去寻找有此标识的元素,然后进行事件的完全解绑。一切都是那么的巧妙!需要注意的一点是,remove()方法在执行的时候会对其自身进行事件解绑,并且该方法可以接受一个选择器参数,以删除其子元素。

实现代码

有了实现思路,编码可以很快搞定。如下:

define(['jquery', 'underscore'], function () { 
var bindDirects = ['delegate', 'bind','on', 'hover', 'blur', 'change', 'click', 'dblclick', 'focus', 'keydown', 'keypress', 'keyup', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'resize', 'scroll', 'select', 'submit']; 
var eMarker = '_addedEvent'; 
_.each(bindDirects, function (eventName) { 
var alias = $.fn[eventName]; 
$.fn[eventName] = function () { 
var $tar = _.isElement(this)?$(this):this; 
var hasEventAdded = $tar.attr(eMarker) || ''; 
var _en = eventName; 
if (hasEventAdded.length) { 
_en += ',' + hasEventAdded; 
} 
$tar.attr(eMarker, _en); 
return alias.apply(_.isElement(this)?$tar:this, [].slice.call(arguments)); 
}; 
}); 
// 为某一个元素移除绑定的事件 
function removeEvents($tar) { 
var addedEventsName = $tar.attr(eMarker); 
if (addedEventsName) { 
addedEventsName.replace(/[^,]+/g, function (eventName) { 
// 全部移除 
if (eventName === 'delegate') { 
$tar.undelegate(); 
} else { 
$tar.unbind(); 
} 
return eventName; 
}); 
} 
} var funcs = ['html','empty']; 
_.each(funcs, function (func) { 
var alias = $.fn[func]; 
$.fn[func] = function () { 
var $tar = _.isElement(this)?$(this):this; 
if($tar.length){ 
$tar.find('*[' + eMarker + ']').each(function (k, subEl) { 
try{ 
removeEvents($(subEl)); 
}catch(e){ 
console.error(e.message); 
} 
}); 
} 
var args = [].slice.call(arguments); 
return alias.apply($tar, args); 
}; 
}); 
// 扩展remove()方法 
var alias = $.fn.remove; 
$.fn.remove = function () { 
var $tar = _.isElement(this)?$(this):this, 
arg = arguments; 
if($tar.length && !arg.length){ 
$tar.find('*[' + eMarker + ']').each(function (k, subEl) { 
try{ 
removeEvents($(subEl)); 
}catch(e){ 
console.error(e.message); 
} 
}); 
} 
if(arg.length){ 
var selector = arg[0]; 
if(_.isString(selector)){ 
$tar.find(selector).each(function(k,curEl){ 
var $cur = $(curEl); 
$cur.find('*[' + eMarker + ']').each(function (k, subEl) { 
try{ 
removeEvents($(subEl)); 
}catch(e){ 
console.error(e.message); 
} 
}); 
removeEvents($cur); 
$cur.remove(); 
}); 
} 
} 
var args = [].slice.call(arguments); 
return alias.apply($tar, args); 
}; 
});

还是那句话,了解的越多,你能做的就越多!
Javascript 相关文章推荐
js 替换
Feb 19 Javascript
js setattribute批量设置css样式
Nov 26 Javascript
jQuery EasyUI API 中文文档 - Draggable 可拖拽
Sep 29 Javascript
jQuery 在光标定位的地方插入文字的插件
May 10 Javascript
JavaScript检测浏览器cookie是否已经启动的方法
Feb 27 Javascript
JavaScript中property和attribute的区别详细介绍
Mar 03 Javascript
基于JavaScript实现网页倒计时自动跳转代码
Dec 28 Javascript
js插件Jcrop自定义截取图片功能
Oct 14 Javascript
React Router v4 入坑指南(小结)
Apr 08 Javascript
Vue-Router的使用方法
Sep 05 Javascript
js正则取值的结果数组调试方法
Oct 10 Javascript
如何测量vue应用运行时的性能
Jun 21 Javascript
jQuery操作select下拉框的text值和value值的方法
May 31 #Javascript
js中的for如何实现foreach中的遍历
May 31 #Javascript
javascript 小数取整简单实现方式
May 30 #Javascript
JQuery给元素绑定click事件多次执行的解决方法
May 29 #Javascript
jquery获取tagName再进行判断
May 29 #Javascript
自定义jquery模态窗口插件无法在顶层窗口显示问题
May 29 #Javascript
Jquery 获取指定标签的对象及属性的设置与移除
May 29 #Javascript
You might like
PHP+Tidy-完美的XHTML纠错+过滤
2007/04/10 PHP
PHP使用DirectoryIterator显示下拉文件列表的方法
2015/03/13 PHP
PHP导出带样式的Excel示例代码
2016/08/28 PHP
JsEasy简介 JsEasy是什么?与下载
2007/03/07 Javascript
基于jQuery试卷自动排版系统
2010/07/18 Javascript
jQuery实现限制textarea文本框输入字符数量的方法
2015/05/28 Javascript
JavaScript实现select添加option
2015/07/03 Javascript
简单实现限制uploadify上传个数
2015/11/16 Javascript
理解JavaScript中Promise的使用
2016/01/18 Javascript
Nodejs如何搭建Web服务器
2016/03/28 NodeJs
利用浮层使select不可选的实现方法
2016/12/03 Javascript
js实现模糊匹配功能
2017/02/15 Javascript
Vuex模块化实现待办事项的状态管理
2017/03/15 Javascript
详解如何将angular-ui的图片轮播组件封装成一个指令
2017/05/09 Javascript
vue elementUI table表格数据 滚动懒加载的实现方法
2019/04/04 Javascript
微信小程序合法域名配置方法
2019/05/06 Javascript
vue中使用props传值的方法
2019/05/08 Javascript
超详细小程序定位地图模块全系列开发教学
2020/11/24 Javascript
[00:36]DOTA2上海特级锦标赛 Alliance战队宣传片
2016/03/04 DOTA
[54:41]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VGJ.T VS paiN
2018/03/31 DOTA
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
python基础教程之基本数据类型和变量声明介绍
2014/08/29 Python
Python爬虫DOTA排行榜爬取实例(分享)
2017/06/13 Python
django输出html内容的实例
2018/05/27 Python
pygame游戏之旅 按钮上添加文字的方法
2018/11/21 Python
python利用Opencv实现人脸识别功能
2019/04/25 Python
在pyqt5中QLineEdit里面的内容回车发送的实例
2019/06/21 Python
用Python实现将一张图片分成9宫格的示例
2019/07/05 Python
使用pandas 将DataFrame转化成dict
2019/12/10 Python
python读取tif图片时保留其16bit的编码格式实例
2020/01/13 Python
opencv 阈值分割的具体使用
2020/07/08 Python
基于python实现图片转字符画代码实例
2020/09/04 Python
Python文件操作及内置函数flush原理解析
2020/10/13 Python
娇韵诗法国官网:Clarins法国
2019/01/29 全球购物
网络安全类面试题
2015/08/01 面试题
《模拟人生4》推出新补丁 “婚礼奇缘”DLC终于得到修复
2022/04/03 其他游戏