[譯] addEventListener 與 onclick,孰優孰劣?

原文出處: addEventListener vs onclick

之因此會想到這個話題,是由於在回顧本身以前寫的爲 button 動態綁定事件的函數時,腦海裏突然浮現出了一個問題:addEventListener 方法,與 onclick="" 相比,各有哪些優勢和缺點呢?因而用關鍵字「StackOverflow addEventListener click func false」進行搜索,第二個結果就是上面的文章連接,現將全文摘要以下:javascript


綁定事件有幾種方式:html

Event Listeners

(addEventListener 以及 IE 的 attachEvent)java

  • IE 8 以及更低版本的 IE 中,須要用 attachEvent 方法:jquery

    element.attachEvent('onclick', function() { /* do stuff here*/ });
  • 對於 IE 9 和更高版本的 IE,以及其它瀏覽器,則要用 addEventListener 方法:api

    element.addEventListener('click', function() { /* do stuff here*/ }, false);

用上面這種方法(DOM level 2 events),理論上能夠爲一個元素綁定無數個事件,實際應用中則決定於客戶端的電腦內存以及瀏覽器。瀏覽器

上面的例子應用了匿名函數這個特性,還能夠使用構造函數或者閉包來添加事件監聽器:閉包

var myFunctionReference = function() { /* do stuff here*/ }

element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);

另外一個重要特性,則是上面這段代碼中最後一行的最後一個參數,用來控制監聽器對於冒泡事件的響應。95%的使用場景中,這個參數都爲 falseattachEvent 以及內聯事件則都沒有能夠實現相同功能的這個參數。框架

Inline Events 內聯事件

(HTML 的 onclick="" 屬性,以及 element.onclick)ide

在全部支持 JavaScript 的瀏覽器中,能夠用下面的方式來添加內聯的事件監聽器。函數

<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>

雖然不少有經驗的開發人員對這種方式嗤之以鼻,可是它的確足夠的簡單粗暴。在這裏你不能使用閉包或者匿名函數,而且控制域也是有限的。

還有另外一種方法:

element.onclick = function () { /*do stuff here */ };

這個方法能實現相同的效果,而且有更多的控制域(由於是 JS 腳本,而不是 HTML 代碼),固然了,也能使用匿名函數、構造函數、閉包。

內聯事件一個明顯的不足:因爲內聯事件是做爲元素屬性保存起來的,這些屬性能夠被覆蓋,因此若是爲同一個事件綁定了多個處理程序,那麼最後一個處理程序會覆蓋以前的程序(多謝 @謙龍 指出此處的翻譯錯誤)。

var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };

運行上面的示例,將只會看到「did stuff #2」——第二行代碼覆蓋了默認的內聯 onclick 屬性,第三行代碼又將第二行代碼覆蓋了,因此會產生這樣的結果。

誰是最佳方案?

要回答這個問題,就要考慮各個瀏覽器的兼容性,以及實際需求了。即便如今只須要爲一個元素綁定一個事件,可是之後極可能還要同時再綁定別的事件,這個時候,就須要用 attachEventaddEventListener 了,不然用內聯方法就能夠搞定了。

jQuery 以及其它的 JavaScript 框架,已經將各個瀏覽器的 DOM level 2 events 的實現以通用模型的形式封裝起來了,因此經過 jQuery 能夠很方便地寫出適用於全部瀏覽器的代碼:

$(element).on('click', function () { /* do stuff */ });

在解決問題的時候,不要簡單地就事論事,好比這篇文章討論的就是如何添加事件監聽器,那就不妨寫一個適用於全部瀏覽器的方法:

function addEvent(element, evnt, funct){
  // if else 結構可用三元運算符 ? : 來精簡
  // 這裏之因此要這樣寫,是便於讀者理解
  if (element.attachEvent) // IE 8 及更低版本瀏覽器
   return element.attachEvent('on'+evnt, funct);
  else // IE 8 及以上,或其它瀏覽器
   return element.addEventListener(evnt, funct, false);
}

// 調用示例
addEvent(
    document.getElementById('myElement'),
    'click',
    function () { alert('hi!'); }
);

相關文獻

相關文章
相關標籤/搜索