世界本该如此!
所以,在现代浏览器,如果你将一个元素从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);
};
});
还是那句话,了解的越多,你能做的就越多!
移除元素,解绑事件
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 群星《青春重置计划9新的凡人歌》[320KMP3][89.41MB]
- 苏曼《苏曼的夜晚HQII》[低速原抓WAV+CUE]
- 【电影原声】汉斯·季默《星际穿越》2014[FLAC+CUE整轨]
- 诹访内晶子AkikoSuwanai巴赫:小提琴协奏曲《J.S.BachViolinConcertos》(flac)
- 王力宏《十八般武艺》[低速原抓WAV+CUE]
- 王力宏《十八般武艺》[低速原抓WAV+CUE]
- 【爵士乐】VA-2024-ParamountJazzLoungeChillingExperience(FLAC)
- 群星《离歌 网剧原声带》[320K/MP3][249.78MB]
- 群星《离歌 网剧原声带》[FLAC/分轨][538.53MB]
- 群星《承欢记 电视剧影视原声带》[320K/MP3][109.99MB]
- 【欧美乡村】JohnnyLee-2024-13thOfJulyandEmotions(FLAC)
- 【流行爵士】PattiAustin-2024-LoveSongs(FLAC)
- 【爵士乐】VA-2024-SupremeLoungeChillSelectionJazzyVibeTunes(FLAC)
- 群星《承欢记 电视剧影视原声带》[FLAC/分轨][219.8MB]
- 群星《乘风2024 第1期》[320K/MP3][110.09MB]