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 事件查询综合 推荐收藏
Mar 10 Javascript
JavaScript格式化数字的函数代码
Nov 30 Javascript
jquery实现图片灯箱明暗的遮罩效果
Nov 15 Javascript
解决jquery中美元符号命名冲突问题
Jan 08 Javascript
用js替换除数字与逗号以外的所有字符的代码
Jun 07 Javascript
微信公众平台开发教程(五)详解自定义菜单
Dec 02 Javascript
页面点击小红心js实现代码
May 26 Javascript
webpack开发环境和生产环境的深入理解
Nov 08 Javascript
Node.js JSON模块用法实例分析
Jan 04 Javascript
webpack4之如何编写loader的方法步骤
Jun 06 Javascript
JavaScript面向对象中接口实现方法详解
Jul 24 Javascript
Webpack中SplitChunksPlugin 配置参数详解
Mar 24 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 strtr() 函数使用说明
2008/11/21 PHP
PHP管理内存函数 memory_get_usage()使用介绍
2012/09/23 PHP
laravel 数据验证规则详解
2019/10/23 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
在页面上点击任一链接时触发一个事件的代码
2007/04/07 Javascript
js判断两个日期是否相等的方法
2013/09/10 Javascript
JavaScript实现的一个倒计时的类
2015/03/12 Javascript
浅谈javascript属性onresize
2015/04/20 Javascript
如何在Linux上安装Node.js
2016/04/01 Javascript
微信小程序  自定义创建详细介绍
2016/10/27 Javascript
BootStrap轮播HTML代码(推荐)
2016/12/10 Javascript
canvas实现图像放大镜
2017/02/06 Javascript
Spring Boot+AngularJS+BootStrap实现进度条示例代码
2017/03/02 Javascript
jQuery插件FusionCharts实现的2D饼状图效果【附demo源码下载】
2017/03/03 Javascript
Js经典案例的实例代码
2018/05/10 Javascript
vue跳转同一个组件,参数不同,页面接收值只接收一次的解决方法
2019/11/05 Javascript
linux 下以二进制的方式安装 nodejs
2020/02/12 NodeJs
Python回调函数用法实例详解
2015/07/02 Python
Python DataFrame.groupby()聚合函数,分组级运算
2018/09/18 Python
在Pytorch中使用样本权重(sample_weight)的正确方法
2019/08/17 Python
PyCharm搭建Spark开发环境的实现步骤
2019/09/05 Python
tensorflow中tf.slice和tf.gather切片函数的使用
2020/01/19 Python
django 解决自定义序列化返回处理数据为null的问题
2020/05/20 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
2021/01/07 Python
微信浏览器左上角返回按钮拦截功能
2017/11/21 HTML / CSS
HTML5 Canvas绘制圆点虚线实例
2015/01/01 HTML / CSS
h5调用摄像头的实现方法
2016/06/01 HTML / CSS
卡骆驰新加坡官网:Crocs新加坡
2018/06/12 全球购物
工商行政处罚决定书
2015/06/24 职场文书
Nginx 过滤静态资源文件的访问日志的实现
2021/03/31 Servers
详解MySQL的半同步
2021/04/22 MySQL
MySQL EXPLAIN输出列的详细解释
2021/05/12 MySQL
解决Navicat for MySQL 连接 MySQL 报2005错误的问题
2021/05/29 MySQL
Java实现添加条码或二维码到Word文档
2022/06/01 Java/Android
MySQL中JOIN连接的基本用法实例
2022/06/05 MySQL
nginx静态资源的服务器配置方法
2022/07/07 Servers