事件監(jiān)聽器與內(nèi)聯(lián)事件的區(qū)別 addEventListener vs onclick

我們都知道,在javascript的DOM操作中,事件監(jiān)聽器與內(nèi)聯(lián)事件這兩個(gè)方法可以實(shí)現(xiàn)相同的功能,那到底他們有何區(qū)別呢?

事件監(jiān)聽器Event Listeners (addEventListener and IE's attachEvent)
<pre>
element.attachEvent()只能使用于IE8及以下瀏覽器;
element.attachEvent('onclick', function() { /* do stuff here*/ });
</pre>

在大多數(shù)其它的其它瀏覽器包括IE9+,你可以按如下格式使用:
element.addEventListener('click', function() { /* do stuff here*/ }, false);

通過這種方式(DOM Level 2 events),我們可以附加無(wú)限個(gè)事件到同一個(gè)元素,唯一限制我們的就是客戶端的內(nèi)存和其它相關(guān)瀏覽器相關(guān)的性能了。

這種方式我們可以靈活地使用anonymous function、function reference或“閉包”:
<pre>
var myFunctionReference = function() { /* do stuff here*/ }

element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
</pre>

另一個(gè)重要的addEventListener的特點(diǎn)是最后一個(gè)參數(shù),用來控制事件監(jiān)聽器是如何來響應(yīng)事件的傳播機(jī)制的(也就是說是否啟用capture)。當(dāng)然,我用的是false在上例中,意思是不使用capture用bubble式,默認(rèn)的方式,也是約95%的案例所用的處理方式。

但這個(gè)參數(shù)對(duì)于attachEvent()或元素內(nèi)聯(lián)事件inline events來說卻并沒有一個(gè)相應(yīng)的參數(shù)來處理。

元素的內(nèi)聯(lián)事件Inline events

Ex:
(HTML onclick="" property and element.onclick)

大多數(shù)主流的瀏覽器支持內(nèi)聯(lián)事件Inline event中執(zhí)行javascript代碼,我們可以放置一個(gè)事件監(jiān)聽器event listener到元素的屬性上,類似如下:

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

大多數(shù)有經(jīng)驗(yàn)的開發(fā)者會(huì)盡量避開這種方式,但他確實(shí)能達(dá)到想要的效果;
因?yàn)樗?jiǎn)單粗暴直接。
在此處,你可以不用“閉包”和匿名函數(shù)anonymous functions(盡管從類別上來說這個(gè)處理器自身就是一個(gè)匿名函數(shù)),因?yàn)槟隳芸刂频淖饔糜蚴怯邢拗频摹?/p>

另一種方法是:

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

這種方法其實(shí)是等價(jià)于上面的內(nèi)聯(lián)事件的,只不過內(nèi)聯(lián)javascript希望能夠使得你能有更多的作用域方面的控制(因此,你可以編寫一個(gè)JavaScript腳本,而不是只有HTML)而且能夠使用匿名函數(shù)、函數(shù)引用和“閉包”。

不過,相比以上方式的簡(jiǎn)單直接而言他們最大的缺點(diǎn)就非常突出了,我們可以也僅僅只可以添加一個(gè)內(nèi)聯(lián)事件,因?yàn)閮?nèi)聯(lián)事件是作為元素的特性/屬性attribute/property來存儲(chǔ)在元素element上的,也就是說,元素的屬性是可以覆寫的.
看下例:
<pre>
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
</pre>

我們點(diǎn)擊element元素時(shí),可以看到僅僅只有"Did stuff #2"生效,因?yàn)榈诙€(gè)值覆蓋了第一個(gè)分配的值,而且,同時(shí)我們也覆蓋了元素原生的內(nèi)聯(lián)HTML的onclick特性/屬性property,具體參看: http://jsfiddle.net/jpgah/

哪一種更好?

這個(gè)問題關(guān)乎瀏覽器兼容性的需要以及我們自身的需要,是否我們真的需要附加多個(gè)事件到同一個(gè)元素上呢?是否我們的項(xiàng)目更具前瞻性,可以用更超前的方式?如果是attachEvent()和addEventListener()都可以考慮,如果不是,一個(gè)小小的內(nèi)聯(lián)元素inline event也能搞惦這個(gè)把戲。

不過jQuery和一些其它類似的javascript框架已經(jīng)把這些問題打包成了通用的解決方案了,同樣的代碼用jQuery來實(shí)現(xiàn)就很簡(jiǎn)單了,而且所有的不同類型的瀏覽器都兼容:
$(element).on('click', function () { /* do stuff */ });

最后,不要試著用一種方式來做這個(gè)事情,我們可以小改動(dòng)一下來照顧一下老版本的瀏覽器:

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!'); }
);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容