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 相关文章推荐
jQuery侧边栏随窗口滚动实现方法
Mar 04 Javascript
jQuery给元素添加样式的方法详解
Dec 30 Javascript
不用一句js代码初始化组件
Jan 27 Javascript
AngularJS 入门教程之HTML DOM实例详解
Jul 28 Javascript
JavaScript中无法通过div.style.left获取值的解决方法
Feb 19 Javascript
利用Javascript获取选择文本所在的句子详解
Dec 03 Javascript
详解JavaScript 为什么要有 Symbol 类型?
Apr 03 Javascript
webpack4之如何编写loader的方法步骤
Jun 06 Javascript
利用vue-i18n实现多语言切换效果的方法
Jun 19 Javascript
vue+element搭建后台小总结 el-dropdown下拉功能
Apr 10 Javascript
JavaScript利用html5新方法操作元素类名详解
Nov 27 Javascript
VUE解决跨域问题Access to XMLHttpRequest at
May 06 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计数器的实现代码
2013/06/08 PHP
php通过修改header强制图片下载的方法
2015/03/24 PHP
php中smarty变量修饰用法实例分析
2015/06/11 PHP
php版微信小店API二次开发及使用示例
2016/11/12 PHP
php 使用expat方式解析xml文件操作示例
2019/11/26 PHP
用于deeplink的js方法(判断手机是否安装app)
2014/04/02 Javascript
js中hash和ico的关联分析
2015/02/05 Javascript
js实现背景图片感应鼠标变化的方法
2015/02/28 Javascript
jquery带翻页动画的电子杂志代码分享
2015/08/21 Javascript
jQuery操作基本控件方法实例分析
2015/12/31 Javascript
BootStrap实用代码片段之一
2016/03/22 Javascript
jQuery使用Selectator插件实现多选下拉列表过滤框(附源码下载)
2016/04/08 Javascript
基于JavaScript实现回到页面顶部动画代码
2016/05/24 Javascript
详解vue的数据binding绑定原理
2017/04/12 Javascript
VueJs 将接口用webpack代理到本地的方法
2017/11/27 Javascript
使用electron制作满屏心特效的示例代码
2018/11/27 Javascript
浅析微信小程序自定义日历组件及flex布局最后一行对齐问题
2020/10/29 Javascript
JavaScript构造函数原理及实现流程解析
2020/11/19 Javascript
[01:46]新英雄登场
2019/09/10 DOTA
Python3实现的简单工资管理系统示例
2019/03/12 Python
使用TensorFlow直接获取处理MNIST数据方式
2020/02/10 Python
Jupyter加载文件的实现方法
2020/04/14 Python
PyInstaller将Python文件打包为exe后如何反编译(破解源码)以及防止反编译
2020/04/15 Python
CSS3+Sprite实现僵尸行走动画特效源码
2016/01/27 HTML / CSS
英国领先的维生素和营养补充剂直接供应商:Healthspan
2019/04/22 全球购物
2019年分享net面试的经历和题目
2016/08/07 面试题
在c#中using和new这两个关键字有什么意义
2013/05/19 面试题
如何开启linux的ssh服务
2015/02/14 面试题
申报职称专业技术个人的自我评价
2013/12/12 职场文书
团代会宣传工作方案
2014/05/08 职场文书
酒后驾车标语
2014/06/30 职场文书
企业标语大全
2014/07/01 职场文书
2015年为民办实事工作总结
2015/05/26 职场文书
解决IIS7下无法绑定https主机的问题
2022/04/29 Servers
windows系统安装配置nginx环境
2022/06/28 Servers
PostgreSQL常用字符串分割函数整理汇总
2022/07/07 PostgreSQL