考慮下面這種情境:如果1個div下面有3個button,點擊每個按鈕的時候,需要列印出當前按鈕的ID。
<div id="parent"><input type="button" id="a" value="1"></input><input type="button" id="b" value="2"></input><input type="button" id="c" value="3"></input></div>
方式1:使用JQuery選取器,給每個按鈕都綁定自己的事件處理函數。
$("#parent :button").click(function(){alert($(this).attr("id"));})
方式2:利用事件委託機制,只給按鈕的父元素繫結事件。
$("#parent").delegate(":button","click",function(){alert($(this).attr("id"));});
delegate這個API的函數簽名如下:
delegate(selector, [type], [data], fn)
selector:
代表JQuery中的選取器,用來過濾觸發事件的元素。上面的parent元素下面有a、b、c這3個按鈕,如果點擊按鈕b的時候,不列印出它的ID。那麼可以通過如下代碼實現:
$("#parent").delegate(":button[id!='b']","click",{},function(){alert($(this).attr("id"));});
type:
附加到元素的一個或多個事件,由空格分隔多個事件值。
data
傳遞給事件處理函數的參數值。
$("#parent").delegate(":button","click",{name:123},function(event){alert(event.data.name);});
fn
當事件發生時候,調用的處理函數。
delegate()還有一個非常重要的性質:使用delegate() 方法的事件處理常式適用於當前已經存在或未來新增的元素。
下面的代碼中,我們點擊test按鈕會新產生1個button,當點擊這個新產生的button時,仍然會列印出它的id。
<script src="jquery-1.11.1.js"></script><script>$(function(){$("#parent").delegate(":button","click",function(event){alert($(this).attr("id"));});$("#test").click(function(event){$("#parent").append('<input type="button" id="d" value="4"></input>');});})</script><body><input type="button" id="test" value="test"><div id="parent"><input type="button" id="a" value="1"></input><input type="button" id="b" value="2"></input><input type="button" id="c" value="3"></input></div></body>
那麼delegate()是怎麼做到的 呢。很簡單,利用javascript中的事件冒泡機制。當子項目產生1個事件的時候,如果沒有禁止這個事件的傳播,那麼父元素也會感知到這個事件(父元素上的事件處理函數被調用)。而且通過Event對象,能夠拿到最初觸發事件的元素。下面的代碼,我們自己實現了1個簡易的事件委託機制。
<script src="jquery-1.11.1.js"></script><script>$(function(){$("#parent").click(":button",function(event){// target是最初觸發事件的DOM元素。var domId = event.target.id;// 過濾元素var filter = event.data;if($(event.target).is(filter)){alert(domId);}});})</script><body><div id="parent"><input type="button" id="a" value="1"></input><input type="button" id="b" value="2"></input><input type="button" id="c" value="3"></input><input type="text" id="d" value="d"></input></div></body>
delegate和undelegate,很類似於bind和unbind,這裡提一下:使用undelegate取消事件委託的時候,也可以使用事件命名空間機制。這篇文章中用bind和unbind作為例子,詳細的介紹了事件命名空間機制,以及使用方式。