文章出處

  先說下將這個話題的起因:最近發現公司的功能代碼,很多在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 }

  當然,在銷毀生成遮罩時,也應對應的銷毀自定義綁定的擴展方法,這里就不叨叨了~

  via:cnblogs.com/walls/p/4253663.html

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()