JavaScript跨瀏覽器綁定事件函數的優化

轉載自:http://www.cnblogs.com/yugege/p/5169998.htmlhtml

 JavaScript做爲一門基於事件驅動的語言(特別是用在DOM操做的時候),咱們經常須要爲DOM綁定各類各樣的事件。然而,因爲低版本的IE的不給力,在綁定事件和移除事件監聽上都不同凡響,咱們經常須要本身封裝一個跨瀏覽器綁定(移除)事件的函數。跨瀏覽器添加(移除)DOM事件的一種很是經典的實現代碼以下:chrome

複製代碼
//跨瀏覽器添加事件
function addHandler(target, eventType, handler) {
  if(target.addEventListener) { //DOM2 events
    target.addEventListener(eventType, handler, false);
  } else { //IE
    target.attachEvent("on" + eventType, handler);
  }
}
 
//跨瀏覽器移除事件
function removeHanler(target, eventType, handler) {
  if(target.removeEventListener) { //DOM2 events
    target.removeEventListener(eventType, handler, false);
  } else { //IE
    target.detachEvent("on", eventType, handler);
  }
}
複製代碼

    上面代碼的實現思路是,首先判斷瀏覽器是否支持DOM2的事件,若是支持,就用addEventListener()進行添加事件,用removeEventListener來移除事件。若是不支持,那麼默認就是低版本的ie瀏覽器了,並使用ie特有的方法。瀏覽器

    乍一看,上面的代碼好像已經充分優化了。隱藏的性能問題在於每次函數調用時都會作重複工做——檢測瀏覽器的類型。這是比較消耗性能,特別是你綁定大量事件,反覆調用的時候。事實上,這是沒必要要的,咱們只須要判斷一次就行的了。由於一旦頁面加載完成後,瀏覽器的類型已是肯定了的,不可能說,如今是IE,而後瀏覽着瀏覽着忽然就會變成了chrome的了。因此,咱們應該對上面代碼進行優化,使其只須要檢測一次瀏覽器。有兩種方法能夠實現只檢測一次,下面分別來探討一下這兩種方法。
  第一種是,在第一次調用添加(移除)事件函數的時候,檢測並決定使用哪一種方法來綁定或者移除事件,而後重寫函數,用一個包含正確操做的新的函數覆蓋舊的函數,而且在舊的函數最後調用該這個新的函數。上面代碼改寫後以下:
複製代碼
//添加事件
function addHandler(target, eventType, handler) {
 
  //檢測瀏覽器類型,而且重寫addHanler方法
  if(target.addEventListener) { //DOM2
    addHandler = function(target, eventType, handler) {
      target.addEventListener(eventType, handler, false);
    };
  } else { //IE
    addHandler = function(target, eventType, handler) {
      target.attachEvent("on" + eventType, handler);
    };
  }
   
  //調用新的函數
  addHandler(target, eventType, handler);
}
 
//移除事件removeHanler
function removeHandler(target, eventType, handler) {
 
  //檢測瀏覽器類型,而且重寫removeHandler方法
  if(target.removeEventListener) { //DOM2
    removeHandler = function(target, eventType, handler) {
      target.removeEventListener(eventType, handler, false);
    };
  } else { //IE
    removeHandler = function(target, eventType, handler) {
      target.detachEvent("on" + eventType, handler);
    };
  }
 
  //調用新的函數
  removeHandler(target, eventType, handler);
}
複製代碼

    須要注意的是,咱們在兩個函數的最後一行,都調用了被重寫了的新函數,好比addHandler(target, eventType, handler);和removeHandler(target, eventType,handler);這是必要的,由於咱們用新的函數覆蓋了舊的函數,必需要在舊的函數裏調用新的函數它纔會執行一次。函數

    還有一種優化方法是,提早檢測瀏覽器類型,並把正確的操做函數賦值給一個變量(或者說是使用函數表達式)。咱們能夠使用一個三目條件運算符(?...:)來實現,代碼以下:
複製代碼
//綁定事件
var addHandler = document.body.addEventListener ?
          function(target, eventType, handler) { //DOM2
            target.addEventListener(eventType, handler,false);
          } :
          function(target, eventType, handler) { //IE
            target.attachEvent("on" + eventType, handler);
          };
//移除事件 var removeHandler = document.body.removeEventListener ?             function(target, eventType, handler) { //DOM2               target.removeEventListener(eventType, handler, false);             } :             function(target, eventType, handler) { //IE               target.detachEvent("on" + eventType, handler);             }
複製代碼

    這種方法,比前面比前面那種更加的「積極」,由於他是在函數調用以前就已經去檢測瀏覽器類型了,調用的時候立刻就能夠正確的去綁定事件。性能

PS:
參考資料: Nicbolas C.Zakas 《High Performance JavaScript》;chapter 8 ;Don’t Repeat Work
該書目前好像只有英文版而尚未中文版的。若是有須要的能夠Google一下,下載個電子版的來看一下
相關文章
相關標籤/搜索