onlick與addEventListener

問題:

addEventListener 和 onclick 有什么不同嗎渊额?

var h=document.getElementById("a");
h.onclick=dothing1;
h.addEventListener("click", dothing2);

上面的代碼放到了一個獨立的.js文件中况木,并且都運行正常旬迹。

高票答案:

這兩種方式都是正確的,但是沒有一個本質上是“最佳”奔垦,而且開發(fā)者可能有恰當的理由選擇同時使用這兩種方法。

事件監(jiān)聽器 (addEventListener 和 IE中的attachEvent)
IE早期版本對JS的實現(xiàn)和其它任何瀏覽器都有著相當大的差距椿猎。在版本<9的情況下惶岭,你需要使用attachEvent[doc]方法,就像這樣:

element.attachEvent('onclick', function() { /* 在這兒做點什么*/ });

在大部分其它的瀏覽器中(包括IE9及以上)按灶,你需要使用addEventListener[doc]方法, 就像這樣:

element.addEventListener('click', function() { /* 在這兒做點什么*/ }, false);

通過使用這個方法 (DOM Level 2 events), 你理論上能夠給單個元素附加無限數量的事件監(jiān)聽器。實際上唯一的限制就是客戶端的內存和其它性能因素鸯旁,這在每個瀏覽器上都各不相同。

上面的例子代表著使用一個匿名函數[doc]. 你也可以使用一個函數引用作為事件監(jiān)聽器[doc] 或者是一個閉包[doc]:

var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);

addEventListener的另一個重要特性就是它最后的那個參數摩疑,該參數控制著監(jiān)聽器如何應答冒泡事件[doc]. 上面的例子里面,我傳遞了false畏铆,這大概在95%的用例上都是標準用法。對于attachEvent或者內聯(lián)事件辞居,并沒有與之對等的參數可供使用。

內聯(lián)事件 (HTML 的onclick=""屬性 和 element.onclick)
在所有支持JS的瀏覽器中瓦灶,你可以內聯(lián)的設置一個事件監(jiān)聽器,意味著寫在HTML代碼里贼陶。你也可能已經見過這種寫法:

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

大部分有經驗的開發(fā)者會避開這種寫法,不過它確實能夠達成目標:簡單且直接碉怔。你在這不能使用閉包或者匿名函數(即使handler函數某種意義上就是一個匿名函數),并且你對作用域的控制是有限的撮胧。

你提到的另一種方法:

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

同內聯(lián)方式基本相同,除了你能對作用域有更多的控制(因為相較于純HTML芹啥,你此刻寫的是一段腳本),你也可以使用匿名函數墓怀、函數引用和閉包汽纠。

內聯(lián)事件明顯的一個缺點就是不像我們上面說的那幾種一樣傀履,你一次只能分配一個內聯(lián)事件。內聯(lián)事件被作為元素上的一個屬性/特性[doc], 這意味著它能夠被重寫。

使用上述HTML例子中的<a>元素:

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

...當你點擊這個元素的時候卧秘,你只能看到"Did stuff #2",因為后面的賦值把前面的onclick覆蓋了翅敌,同時也覆蓋了HTML上原生的onclick屬性。在這里查看demo: http://jsfiddle.net/jpgah/.

哪個是最好的?
答案是看瀏覽器兼容性和需要蚯涮。你當前是否需要為一個元素添加多個事件監(jiān)聽器?將來呢遭顶?多半是這樣的。attachEventaddEventListener是必須的棒旗。如果不需要,那么內聯(lián)事件將擔此重任铣揉。

jQuery和其它JS框架為不同的瀏覽器封裝了一套通用的DOM level 2 events實現(xiàn),所以你可以不用擔心IE的歷史問題搗亂了逛拱,安心寫跨瀏覽器一致的代碼。相同的功能用jQuery寫, 當當當當朽合!:

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

但是俱两,請不要為了這一件小事就引入了一個框架曹步。你可以輕松的實現(xiàn)一個自己的小工具庫來處理老瀏覽器上的問題:

function addEvent(element, evnt, funct){
  if (element.attachEvent)
   return element.attachEvent('on'+evnt, funct);
  else
   return element.addEventListener(evnt, funct, false);
}

// example
addEvent(
    document.getElementById('myElement'),
    'click',
    function () { alert('hi!'); }
);

來這兒試試: http://jsfiddle.net/bmArj/

要把上面所有的因素都考慮進來,除非你以某種其它的方式考慮瀏覽器的差異化(你問題中的代碼可能沒體現(xiàn)出來),那就是IE9 以下addEventListener不被支持箭窜。

文檔和相關參考閱讀

W3 HTML specification, element Event Handler Attributes
element.addEventListener on MDN
element.attachEvent on MSDN
Jquery.on
quirksmode blog "Introduction to Events"
CDN-hosted javascript libraries at Google

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末衍腥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子婆咸,更是在濱河造成了極大的恐慌,老刑警劉巖尚骄,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡憨闰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門鹉动,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人泽示,你說我怎么就攤上這事⌒瞪福” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵埋哟,是天一觀的道長。 經常有香客問我赤赊,道長,這世上最難降的妖魔是什么砍鸠? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮爷辱,結果婚禮上,老公的妹妹穿的比我還像新娘饭弓。我一直安慰自己,他們只是感情好弟断,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著阀趴,像睡著了一般刘急。 火紅的嫁衣襯著肌膚如雪棚菊。 梳的紋絲不亂的頭發(fā)上叔汁,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天检碗,我揣著相機與錄音,去河邊找鬼折剃。 笑死,一個胖子當著我的面吹牛像屋,可吹牛的內容都是我干的。 我是一名探鬼主播开睡,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼篇恒!你這毒婦竟也來了?” 一聲冷哼從身側響起胁艰,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腾么,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體解虱,經...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年殴泰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悍汛。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖离咐,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情宵蛀,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布糖埋,位于F島的核電站窃这,受9級特大地震影響瞳别,放射性物質發(fā)生泄漏。R本人自食惡果不足惜祟敛,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望馆铁。 院中可真熱鬧,春花似錦埠巨、人聲如沸历谍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽勋桶。三九已至,卻和暖如春例驹,著一層夾襖步出監(jiān)牢的瞬間捐韩,已是汗流浹背鹃锈。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留屎债,地道東北人寨蹋。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓扔茅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親召娜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容

  • 聲明:本文來源于http://www.webzsky.com/?p=731我只是在這里作為自己的學習筆記整理一下(...
    angryyan閱讀 7,009評論 1 6
  • ??JavaScript 與 HTML 之間的交互是通過事件實現(xiàn)的雅倒。 ??事件,就是文檔或瀏覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,490評論 1 11
  • 以下文章為轉載蔑匣,對理解JavaScript中的事件處理機制很有幫助棕诵,淺顯易懂,特分享于此校套。 什么是事件? 事件(E...
    jxyjxy閱讀 3,035評論 1 10
  • 事件綁定的方式 給 DOM 元素綁定事件分為兩大類:在 html 中直接綁定 和 在 JavaScript 中綁定...
    Bruce_zhuan閱讀 1,036評論 0 6
  • 01 一部電影正看到高潮妹孙,電腦突然卡住自動關機; 一杯咖啡只喝了幾口获枝,杯子里突然出現(xiàn)了不明昆蟲; 一個以為能相伴到...
    雪小禾閱讀 1,883評論 0 19