五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > JavaScript的事件代理

JavaScript的事件代理

文章來源:365jz.com     點擊數(shù):220    更新時間:2009-09-21 11:05   參與評論

如果你想進一步了解如何用JavaScript來為網(wǎng)頁添加交互性的話,你也許已經(jīng)聽過JavaScript的事件代理(event delegation)了,并且會覺得只有那些牛逼烘烘的JavaScript程序員才會關(guān)心這樣復(fù)雜的設(shè)計模式。事實上,如果你已經(jīng)知道怎么樣去添加JavaScript的事件處理器(event handler),實現(xiàn)事件代理也是件輕而易舉的事情。

JavaScript事件是所有網(wǎng)頁交互性的根基(我指的是真正的互動性,而不僅是那些CSS的下拉菜單)。在傳統(tǒng)的事件處理中,你按照需要為每一個元素添加或者是刪除事件處理器。然而,事件處理器將有可能導(dǎo)致內(nèi)存泄露或者是性能下降——你用得越多這種風(fēng)險就越大。JavaScript事件代理則是一種簡單的技巧,通過它你可以把事件處理器添加到一個父級元素上,這樣就避免了把事件處理器添加到多個子級元素上。

它是怎么運作的呢?

事件代理用到了兩個在JavaSciprt事件中常被忽略的特性:事件冒泡以及目標(biāo)元素。當(dāng)一個元素上的事件被觸發(fā)的時候,比如說鼠標(biāo)點擊了一個按鈕,同樣的事件將會在那個元素的所有祖先元素中被觸發(fā)。這一過程被稱為事件冒泡;這個事件從原始元素開始一直冒泡到DOM樹的最上層。對任何一個事件來說,其目標(biāo)元素都是原始元素,在我們的這個例子中也就是按鈕。目標(biāo)元素它在我們的事件對象中以屬性的形式出現(xiàn)。使用事件代理的話我們可以把事件處理器添加到一個元素上,等待事件從它的子級元素里冒泡上來,并且可以很方便地判斷出這個事件是從哪個元素開始的。

這對我有什么好處呢?

想象一下現(xiàn)在我們有一個10列、100行的HTML表格,你希望在用戶點擊某一單元格的時候做點什么。比如說有一次我就需要讓表格中的每一個單元格在被點擊的時候變成可編輯狀態(tài)。如果把事件處理器加到這1000個單元格將會產(chǎn)生一個很大的性能問題,并且有可能導(dǎo)致內(nèi)存泄露甚至是瀏覽器的崩潰。相反地,使用事件代理的話,你只需要把一個事件處理器添加到table元素上就可以了,這個函數(shù)可以把點擊事件給截下來,并且判斷出是哪個單元格被點擊了。

用代碼寫出來的話是什么樣呢?

代碼很簡單,我們所要關(guān)心的只是如何檢測目標(biāo)元素而已。比方說我們有一個table元素,ID是“report”,我們?yōu)檫@個表格添加一個事件處理器以調(diào)用editCell函數(shù)。editCell函數(shù)需要判斷出傳到table來的事件的目標(biāo)元素??紤]到我們要寫的函數(shù)中可能會重復(fù)用到這一功能,所以我們把它單獨放到一個名為getEventTarget的函數(shù)中:

function getEventTarget(e) {
  e = e || window.event;
  return e.target || e.srcElement;
}

e這個變量表示的是一個事件對象,我們只需要寫一點點跨瀏覽器的代碼來返回目標(biāo)元素。在IE里目標(biāo)元素放在srcElement屬性中,而在其它瀏覽器里則是target屬性。

接下來就是editCell函數(shù)了,這個函數(shù)調(diào)用到了getEventTarget函數(shù)。一旦我們得到了目標(biāo)元素之后,剩下的事情就是看看它是否是我們所需要的那個元素了。

function editCell(e) {
  var target = getEventTarget(e);
  if(target.tagName.toLowerCase() === 'td') {
    // DO SOMETHING WITH THE CELL
  }
}

editCell函數(shù)中,我們通過檢查目標(biāo)元素標(biāo)簽名稱的方法來確定它是否是一個表格的單元格。這種檢查也許過于簡單了點;如果它是這個目標(biāo)元素單元格里的另一個元素呢?我們需要為代碼做一點快速修改以便于其找出我們所需要的那個父級的td元素。如果說有些單元格不需要被編輯怎么辦呢?此種情況下我們可以為那些不可編輯的單元格添加一個指定的樣式名稱,然后在把單元格變成可編輯狀態(tài)之前先檢查它是否不包含那個樣式名稱。選擇總是多樣化的,你只需找到適合你應(yīng)用程序的那一種就可以了。

有哪些優(yōu)點和缺點呢?

JavaScript事件代理帶來的好處有:

  • 那些需要創(chuàng)建的以及駐留在內(nèi)存中的事件處理器少了。這是很重要的一點,我們得到了性能上的提升,同時降低了崩潰的風(fēng)險。
  • 在DOM更新后無須重新綁定事件處理器了。如果你的頁面是動態(tài)生成的,比如說通過Ajax,你不需要再在元素被載入或者卸載的時候來添加或者刪除事件處理器了。

潛在的問題也許并不那么明顯,但是一旦你注意到這些問題,你就可以輕松地避免它們:

  • 你的事件管理代碼有成為性能瓶頸的風(fēng)險,所以盡量使它能夠短小精悍。
  • 不是所有的事件都能冒泡的。blur、focus、loadunload不能像其它事件一樣冒泡。事實上blurfocus可以用事件捕獲而非事件冒泡的方法獲得(在非IE的瀏覽器中),不過我們改天再說這個吧。
  • 在管理鼠標(biāo)事件的時候有些需要注意的地方。如果你的代碼處理mousemove事件的話你遇上性能瓶頸的風(fēng)險可就大了,因為mousemove事件觸發(fā)得非常頻繁。而mouseout則因為其怪異的表現(xiàn)而變得很難用事件代理來管理。

總結(jié)

已經(jīng)有一些使用主流類庫的事件代理示例出現(xiàn)了,比如說用jQueryPrototype以及Yahoo! UI的。你也可以找到那些不用任何類庫的例子,比如說Usable Type blog上的這一個。

在你需要的時候,事件代理將成為你工具箱里一件得心應(yīng)手的工具,而且它真的很容易實現(xiàn)。

如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答!! 點擊進入論壇

發(fā)表評論 (220人查看0條評論)
請自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動的言論。
昵稱:
最新評論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢

· 技術(shù)支持
· 服務(wù)時間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號