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 相关文章推荐
javaScript 关闭浏览器 (不弹出提示框)
Jan 31 Javascript
15款优秀的jQuery导航菜单插件分享
Jul 19 Javascript
基于JavaScript 声明全局变量的三种方式详解
May 07 Javascript
JavaScript中为什么null==0为false而null大于=0为true(个人研究)
Sep 16 Javascript
JavaScript Promise启示录
Aug 12 Javascript
js监听鼠标点击和键盘点击事件并自动跳转页面
Sep 24 Javascript
IE中鼠标经过option触发mouseout的解决方法
Jan 29 Javascript
javascript常见数字进制转换实例分析
Apr 21 Javascript
Vue 中使用vue2-highcharts实现top功能的示例
Mar 05 Javascript
Node.JS用纯JavaScript生成图片或滑块式验证码功能
Sep 12 Javascript
JS使用正则表达式实现常用的表单验证功能分析
Apr 30 Javascript
vue+iview实现手机号分段输入框
Mar 25 Vue.js
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 SPL标准库之SplFixedArray使用实例
2015/05/12 PHP
PHP书写格式详解(必看)
2016/05/23 PHP
PHP Beanstalkd消息队列的安装与使用方法实例详解
2020/02/21 PHP
Mootools 1.2教程(2) DOM选择器
2009/09/14 Javascript
jquery和雅虎的yql服务实现天气预报服务示例
2014/02/08 Javascript
javascript中实现兼容JAVA的hashCode算法代码分享
2020/08/11 Javascript
详解javascript实现瀑布流绝对式布局
2016/01/29 Javascript
在原生不支持的旧环境中添加兼容的Object.keys实现方法
2017/09/11 Javascript
vue 路由页面之间实现用手指进行滑动的方法
2018/02/23 Javascript
JavaScript的Object.defineProperty详解
2018/07/09 Javascript
vue脚手架搭建项目的兼容性配置详解
2018/07/17 Javascript
[00:48]DOTA2国际邀请赛公开赛报名开始 扫码开启逐梦之旅
2018/06/06 DOTA
Python中的匿名函数使用简介
2015/04/27 Python
python遍历数组的方法小结
2015/04/30 Python
Python编程对列表中字典元素进行排序的方法详解
2017/05/26 Python
浅谈python中的数字类型与处理工具
2017/08/02 Python
对python插入数据库和生成插入sql的示例讲解
2018/11/14 Python
django 邮件发送模块smtp使用详解
2019/07/22 Python
基于Django统计博客文章阅读量
2019/10/29 Python
Python算法中的时间复杂度问题
2019/11/19 Python
Python协程 yield与协程greenlet简单用法示例
2019/11/22 Python
Python谱减法语音降噪实例
2019/12/18 Python
基于python 将列表作为参数传入函数时的测试与理解
2020/06/05 Python
在 Python 中使用 7zip 备份文件的操作
2020/12/11 Python
html5实现多文件的上传示例代码
2014/02/13 HTML / CSS
孕妇装中的著名品牌:Isabella Oliver(伊莎贝拉·奥利弗)
2016/10/31 全球购物
蔻驰西班牙官网:COACH西班牙
2019/01/16 全球购物
美国第二大连锁药店:Rite Aid
2019/04/03 全球购物
远程调用的原理
2014/07/05 面试题
综合测评自我鉴定
2013/10/08 职场文书
畜牧兽医本科生的自我评价
2014/03/03 职场文书
会计专业2019暑假实习报告
2019/06/21 职场文书
MySQL pt-slave-restart工具的使用简介
2021/04/07 MySQL
redis连接被拒绝的解决方案
2021/04/12 Redis
浅谈TypeScript 索引签名的理解
2021/10/16 Javascript
Beekeeper Studio开源数据库管理工具比Navicat更炫酷
2022/06/21 数据库