jQuery.live()與Event Delegation

網友Ark剛好問到live(),不知道大家有沒有覺得jQuery.live()具有為"未來元素"設定事件的未卜先知能力很神奇? 至少在乍聽之餘,我覺得很不可思議,莫非它要攔截所有建立元素的過程? 不對,難度很高、沒效率、漏洞也很多,那麼又是怎麼做到的呢?

本草網目官方文件上有詳細的解釋,關鍵在Event Delegation

過去bind()時,會逐一在元素上設定事件,而Event Delegation則是利用事件會Bubble Up的特性,直接把事件掛在document上,網頁上的任何元素觸發事件時,document也會被觸發同樣的事件,透過event.target則可找出觸發事件的真實來源。live()就是透過傳入的Selector比對target元素是否為鎖定對象,若在Selector範圍內,就執行指定的事件函數。

這裡用個簡單的例子示範如何透過在document上掛click事件攔載<input type="button">的點擊。(有興趣的人可以在Mini jQuery Lab親手玩看看)

Body HTML為
<input type="button" id="btn1" value="Button1" />
<input type="button" id="btn2" value="Button2" />

Script為
$(document).click(function(e) {
    alert($(e.target).val() + " is clicked!");
});

如此,我們雖然沒有$("input:button").click(fn),一樣可以抓到按鈕的Click事件。

最後補充一下Event Delegation的優缺點。它的優點為:

  • 可降低Event Handler的數量,減少記憶體的使用,有利於效能與穩定性。例如那種要處理數萬個<td>事件的場合,就可以考慮。
  • 元素新增、移除、更動時,不用反覆掛載或卸除事件處理函數。

缺點則是:

  • 掛在document上的事件函數會在網頁上每一個元素被觸發事件時都被呼叫一次,由於執行頻率很高,若沒寫好可能重創效能。
  • 不是所有的事件都會浮到上層,例如: blur, focus, load, unload就不適用。
  • 應用在mouseover之類的滑鼠事件時需特別留意,由於呼叫頻率高,一樣要小心程式寫法以免拖垮效能。

了解了Event Delegation的持性,大家可以善用它有效率地滿足特定的情境需求囉!

歡迎推文分享:
Published 15 March 2009 03:44 AM 由 Jeffrey
Filed under: ,


意見

# Ark said on 15 March, 2009 09:24 AM

恩~我那個瓶頸大概知道了~忘記來這邊講講

想不到有人念念不忘

live()就是透過傳入的Selector比對target元素是否為鎖定對象,若在Selector範圍內,就執行指定的事件函數。<==這句話應該標亮顯示

這剛好可以解釋 $(<DOM ELEMENT>) 與 $(Selector)的差異

$(Selector).Selector會回傳Selector

$(<DOM ELEMENT>).Selector 會回傳""空白

所以live()死的剛好而已

# Tony said on 07 July, 2009 12:19 AM

那我要怎麼取得 e.target 的 id ?

# Jeffrey said on 07 July, 2009 08:55 AM

to Tony, 我習慣用e.target.id,$(e.target).attr("id")應該也行.

# Bottle said on 17 July, 2009 12:16 PM

submit事件好像也不太行

我練習的東西在火狐可以,在IE就不行

IE似乎抓不到我用live連結的submit事件

不過我是用了form套件就是了

# Jeffrey said on 17 July, 2009 05:08 PM

to Bottle, 依官方文件的說法,submit不在live的支援範圍內,我之前想用change也失敗了。

Currently not supported: blur, focus, mouseenter, mouseleave, change, submit,submit在不支援之列(依我自己的測試,發現所謂不支援是指不是所有瀏覽器都可以支援,有些事件在某些瀏覽器是可以live的)  docs.jquery.com/.../live

# azure said on 17 November, 2009 01:46 AM

請教一下..

有辦法將live()和one()搭配使用嗎 ?

$('button').one("click", function(){

alert('我只能按一次');

})

# Jeffrey said on 17 November, 2009 10:36 AM

to azure, 依我的想法,在live的事件裡呼叫die,應該就可以達到跟one相當的效果。

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 

請輸入以上的數字:

搜尋

Go

<March 2009>
SunMonTueWedThuFriSat
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234
 
RSS
【工商服務】

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication