jQuery移除元素自动解绑事件实现思路及代码
世界本该如此!
所以,在现代浏览器,如果你将一个元素从DOM树种进行移除的时候,浏览器会自动帮你绑定的事件进行解绑以释放其占用的内存。也许你猜到了,较老版本的浏览器则不会主动去做这件事,所以,当你的应用在较老版本的浏览器运行的越久,其消耗内存越多,应用就会变得越来越卡。因此,需要我们自己对要删除的元素进行事件解绑。
实现思路
用jQuery将元素移除的基本方法常用的有三个,一个是remove()方法,一个是html()方法,一个是empty()方法。我们可以对此三个方法进行进一步的封装,我们会在事件绑定的时候给绑定事件的元素添加一个属性标识,从要删除的元素中去寻找有此标识的元素,然后进行事件的完全解绑。一切都是那么的巧妙!需要注意的一点是,remove()方法在执行的时候会对其自身进行事件解绑,并且该方法可以接受一个选择器参数,以删除其子元素。
实现代码
有了实现思路,编码可以很快搞定。如下:
define(['jquery','underscore'],function(){
varbindDirects=['delegate','bind','on','hover','blur','change','click','dblclick','focus','keydown','keypress','keyup','mousedown','mouseenter','mouseleave','mousemove','mouseout','mouseover','mouseup','resize','scroll','select','submit'];
vareMarker='_addedEvent';
_.each(bindDirects,function(eventName){
varalias=$.fn[eventName];
$.fn[eventName]=function(){
var$tar=_.isElement(this)?$(this):this;
varhasEventAdded=$tar.attr(eMarker)||'';
var_en=eventName;
if(hasEventAdded.length){
_en+=','+hasEventAdded;
}
$tar.attr(eMarker,_en);
returnalias.apply(_.isElement(this)?$tar:this,[].slice.call(arguments));
};
});
//为某一个元素移除绑定的事件
functionremoveEvents($tar){
varaddedEventsName=$tar.attr(eMarker);
if(addedEventsName){
addedEventsName.replace(/[^,]+/g,function(eventName){
//全部移除
if(eventName==='delegate'){
$tar.undelegate();
}else{
$tar.unbind();
}
returneventName;
});
}
}
varfuncs=['html','empty'];
_.each(funcs,function(func){
varalias=$.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);
}
});
}
varargs=[].slice.call(arguments);
returnalias.apply($tar,args);
};
});
//扩展remove()方法
varalias=$.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){
varselector=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();
});
}
}
varargs=[].slice.call(arguments);
returnalias.apply($tar,args);
};
});
还是那句话,了解的越多,你能做的就越多!