jQuery中的delegate與live實現方式簡析
delegate和live方法是jQuery在1.4版本中新增的方法。他的作用是事件監聽,但是可以對jQuery對象中新增的DOM對象也作用:
$("body").delegate("p", "click", function(){
$(this).after("<p>Another paragraph!</p>");
});
</script>
上面的這個demo運行效果就是點擊一個段落P標簽將在p標簽后面添加一個p標簽,對于新增的p標簽同樣可以點擊新增一個p標簽,新增的標簽不需要監聽其click事件。live也同理:
$("p").live("click", function(){
$(this).after("<p>Another paragraph!</p>");
});
這個是怎么實現的了?我自己嘗試了一把:首先必須了解事件的冒泡機制。下面的例子將在按鈕 和其容器上同時監聽click事件,根據冒泡的做法,將先觸發按鈕的click事件,然后觸發容器div的click事件。
function handle(e){
//獲取event對象
//標準DOM方法事件處理函數第一個參數是event對象
//IE可以使用全局變量window.event
var evt = window.event?window.event:e;
//獲取觸發事件的原始事件源
//標準DOM方法是用target獲取當前事件源
//IE使用evt.srcElement獲取事件源
var target = evt.target||evt.srcElement;
//獲取當前正在處理的事件源
//標準DOM方法是用currentTarget獲取當前事件源
//IE中的this指向當前處理的事件源
var currentTarget= e?e.currentTarget:this;
//問題:在IE 9下 window.event 與 e 不同 evt沒有currentTarget屬性,e才有currentTarget屬性(視為標準瀏覽器做法??)
alert("src id:"+target.id+"\ncurent target id :"+currentTarget.id);
}
document.getElementById("btn").onclick=handle;
document.getElementById("c").onclick= handle;
}
<input type="button" id="btn" name="" value="button" />
</div>
問題在于處理容器c的click事件是由冒泡觸發的。需要找到真正觸發事件的事件源按鈕btn。標準瀏覽器的event提供了currentTarget屬性獲取原始事件源。否標準瀏覽器IE6/7/8可以直接使用this訪問。這樣div的click事件中可以獲取到真正觸發事件的事件源。
//ps:上面的代碼中有個發現:在調試的時候發現IE 9中的e 和全局變量window.event有區別,IE 9的e的設置完全是按照標準瀏覽器來的。所以e也提供了currentTarget屬性。下面是我調試時候的發現:
其實只要能獲取到冒泡的原始事件源,對于新增的元素,我們通過監聽其父容器事件,然后根據原始事件是否是新增元素,就可以觸發新增元素的事件。這就是所謂的“代理(delegate)”,就是通過容器(未必是父容器)的事件監聽代理新元素的事件。下面用一個超鏈接新增一個按鈕并且在不監聽其事件情況下通過事件冒泡捕獲其事件。





































<input type="button" id="btn" name="" value="button" />
</div>
<a href="###" id="btnadd">添加一個按鈕</a>
新增的按鈕同樣能監聽到其click方法,只是使用其父容器代理click事件在代理新按鈕的click事件
上面的分析也能說明為什么delegate的性能會比live要好。因為live是通過document.body的事件代理了新元素的事件。delegate指定了事件代理的夫容器,這樣事件冒泡的層次會少,性能表現會好。
posted on 2011-04-19 12:07 衡鋒 閱讀(4762) 評論(3) 編輯 收藏 所屬分類: javascript 、Web開發