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 相关文章推荐
dojo 之基础篇(三)之向服务器发送数据
Mar 24 Javascript
js计算页面刷新的次数
Jul 20 Javascript
Mootools 1.2教程(21)——类(二)
Sep 15 Javascript
PHP abstract与interface之间的区别
Nov 11 Javascript
Knockout visible绑定使用方法
Nov 15 Javascript
JavaScript数组去重的方法总结【12种方法,号称史上最全】
Feb 28 Javascript
详解微信小程序缓存--缓存时效性
May 02 Javascript
vue配置接口域名方法总结
May 12 Javascript
vue项目中引入Sass实例方法
Aug 27 Javascript
ionic3双击返回退出应用的方法
Sep 17 Javascript
layui之数据表格--与后台交互获取数据的方法
Sep 29 Javascript
jQuery 选择器用法基础入门示例
Jan 04 jQuery
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中for循环语句的几种变型
2006/11/26 PHP
探讨PHP使用eAccelerator的API开发详解
2013/06/09 PHP
Jquery.addClass始终无效原因分析
2013/09/08 Javascript
JavaScript中为什么null==0为false而null大于=0为true(个人研究)
2013/09/16 Javascript
JavaScript改变HTML元素的样式改变CSS及元素属性
2013/11/12 Javascript
JavaScript分析、压缩工具JavaScript Analyser
2014/12/31 Javascript
JavaScript原生对象之Number对象的属性和方法详解
2015/03/13 Javascript
7个有用的jQuery代码片段分享
2015/05/19 Javascript
javascript+ajax实现产品页面加载信息
2015/07/09 Javascript
jQuery实现可编辑的表格实例讲解(2)
2015/09/17 Javascript
jQuery实现标题有打字效果的焦点图代码
2015/11/16 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
2016/03/31 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
2017/03/14 Javascript
详解基于vue-cli3.0如何构建功能完善的前端架子
2018/10/09 Javascript
vuex的module模块用法示例
2018/11/12 Javascript
vue中子组件传递数据给父组件的讲解
2019/01/27 Javascript
详解Vue.js 作用域、slot用法(单个slot、具名slot)
2019/10/15 Javascript
Vue学习笔记之计算属性与侦听器用法
2019/12/07 Javascript
在vue中created、mounted等方法使用小结
2020/07/21 Javascript
vue组件中节流函数的失效的原因和解决方法
2020/12/02 Vue.js
[04:15]DOTA2-DPC中国联赛 正赛 Ehome vs Aster 选手采访
2021/03/11 DOTA
浅谈python for循环的巧妙运用(迭代、列表生成式)
2017/09/26 Python
Python设计模式之工厂模式简单示例
2018/01/09 Python
python画图--输出指定像素点的颜色值方法
2019/07/03 Python
使用python os模块复制文件到指定文件夹的方法
2019/08/22 Python
Python如何输出整数
2020/06/07 Python
阿迪达斯奥地利官方商城:adidas.at
2016/10/16 全球购物
班级聚会策划书
2014/01/16 职场文书
孝老爱亲模范事迹
2014/01/24 职场文书
高三毕业典礼主持词
2014/03/27 职场文书
公司口号大全
2014/06/11 职场文书
药店采购员岗位职责
2014/09/30 职场文书
自信主题班会
2015/08/14 职场文书
2016秋季校长开学典礼致辞
2015/11/26 职场文书
Python实现滑雪小游戏
2021/09/25 Python
解析mybatis-plus中的resultMap简单使用
2021/11/23 Java/Android