利用on和off方法编写高效的js代码
先说下将这个话题的起因:最近发现公司的功能代码,很多在dom对象删除以后,其声明的绑定在window上的resize事件还一直存在,导致相同的功能代码执行了几次。对于我这种轻微代码洁癖的人来说,简直是个大坑。
所以,这里以jQuery的resize方法为例,讲解下我所理解的高效写法。
先看一下普通的在window下绑定resize事件:
1 $(window).resize(function(){ 2 console.log("hehe"); 3 }); 4 $(window).resize(function(){ 5 console.log("hehe2"); 6 });
触发了几次resize后的执行结果如下:
两个事件处理程序不会互相覆盖是因为,jQuery的方法都是DOM2级的(这里就不细说了)。而问题就出在这里,如果再删除DOM对象后,其特有的、非绑定在本身的响应方法没有对应删除的话,会一直积累下来,像幽灵一般。而这里就是所谓的影响性能,让浏览器宝贵的CPU被无效的功能代码消耗掉,用户体验也在积累一定数量级该幽灵代码后,逐级降低,甚至卡死。
怎么解决呢?当然是kill掉!
如果用unbind方法,是可以进行清除操作,但是关键有时候会勿删,特别是多人协作的团队。所以,on和off方法就派上用场了!
将resize方法改造一下:
1 $(window).on("resize.fn1", function(){ 2 console.log("hehe"); 3 }); 4 $(window).on("resize.fn2", function(){ 5 console.log("hehe2"); 6 });
重点是on方法的第一个参数:resize.fn1。实心点之前,是该window对象要绑定的resize方法;实心点之后是为该方法取的一个别名,用于标识该方法(注意不能有空格,这是我的一位同事遇到的)。
这个别名,是用于调用off方法时,删除指定对应的处理程序。
如我要删除输出“hehe”的处理程序,代码如下:
1 $(window).off("resize.fn1");
这样,就可以把不需要的功能代码精确销毁,而不会导致勿删。
另外提醒下,resize事件可以根据需要写n个,然后,你可以根据业务的功能划分,为相同生存期的代码标识相同的别名,以便可以统一销毁。
扩展一下思路:
一般我们写扩展性比较好的函数,比如生成一个遮罩,一般都会预留一个calbackl方法,如下:
1 function overlay(options){ 2 var default = { 3 /*其他参数 */ 4 callback:false 5 }; 6 var settings = $.extend({}, default, options); 7 if(!!settings.callback){ 8 settings.callback(); 9 } 10 }
但是,我们可以把扩展性做得更好,比如当遮罩初始化生成时,在window上绑定一个resize事件,输出1
1 var data = { 2 /*其他参数*/ 3 extFn : [{ 4 obj:$(window), 5 name:"resize.overlay", 6 fn:function(){ 7 console.log(1); 8 } 9 }] 10 }; 11 12 overlay(data); 13 14 function overlay(options){ 15 var default = { 16 /*其他参数*/ 17 callback:false, 18 extFn:[] 19 }; 20 var settings = $.extend({}, default, options); 21 22 if(settins.extFn.length > 0){ 23 var extFn_obj, extFn_name, extFn_fn; 24 25 for(var i = 0, len = settings.extFn.length; i < len; i++){ 26 extFn_obj = settings.extFn[i].obj; 27 extFn_name = settings.extFn[i].name; 28 extFn_fn = settings.extFn[i].fn; 29 extFn_obj.off(extFn_name);//销毁旧的事件绑定 30 extFn_obj.on(extFn_name, extFn_fn);//添加新的事件绑定 31 } 32 } 33 34 /*其他方法及callback*/ 35 }
当然,在销毁生成遮罩时,也应对应的销毁自定义绑定的扩展方法,这里就不叨叨了~
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。