JQuery手動觸發事件API之:通過代碼看清trigger與triggerHandler的差別,
本文只討論JQuery如何手動觸發DOM上綁定的事件處理函數,至於如何給DOM綁定事件處理函數,可以參考這篇文章。測試環境是IE11/FF17/Chrome39,JQuery版本是1.11.1和2.1.1都測試過。
下面這段js代碼給button綁定了click事件處理函數,第一種是我們最常用的做法;第二種使用了自訂參數。
// 綁定事件的時候不自訂參數$("#button").bind("click",function(event){ alert("clicked");}); // 使用自訂參數$("#button").bind("click",{name:"aty"}, function(event){ alert("params=" + event.data.name); });
如果我們想手動觸發click事件,最常見的做法是通過$("#button").click()來觸發,這種做法姑且叫方式一吧。
方式一觸發事件有3個特點:
1. 會產生事件冒泡
2. 不會阻止事件在瀏覽器下的預設行為
3. 觸發事件的時候,不能傳遞自訂參數
JQuery還允許我們使用trigger和triggerHandler手動觸發事件,這2種方式有什麼差別呢?下面我們來看一下。
1. trigger會觸發事件冒泡,而triggerHandler則不會。這一點上trigger與方式一是一致的。
<script> $(function(){ $("#outA").click(function(){ alert("A"); }); $("#outB").click(function(){ alert("B"); }); $("#outC").click(function(){ alert("C"); }); // 使用trigger,依次C、B、A$("#outC").trigger("click");// 使用trigger,只會列印出C$("#outC").triggerHandler("click"); }); </script> <body> <div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;"> <div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;"> <div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div> </div> </div> </body>
2. triggerHandler只觸發jQuery對象集合中第一個元素的事件處理函數,而trigger則觸發所有對象的事件處理函數。
<script>$(function(){// 給按鈕綁定click事件處理函數$("input[type=button]").click(function(event){alert($(this).attr("id"));});// 選中的button集合中,只觸發第一個button的click事件,只列印出1$("input[type=button]").triggerHandler("click");// 選中的button集合中,觸發所有button的click,列印出1,2,3$("input[type=button]").trigger("click");})</script><body><input type="button" id="1"><input type="button" id="2"><input type="button" id="3"></body>
3. trigger會觸發事件的預設行為,triggerHandler則會阻止事件的預設行為。這一點上trigger與方式一相同。
<script>$(function(){$("#btn-trigger").click(function(event){$("#text1").trigger("focus");});$("#btn-triggerHandler").click(function(event){$("#text2").triggerHandler("focus");});})</script><body><input type="text" id="text1" tabIndex="0"><input type="text" id="text2" tabIndex="1"><input type="button" id="btn-trigger" value="trigger" tabIndex="2"><input type="button" id="btn-triggerHandler" value="triggerHandler" tabIndex="3"></body>
點擊trigger按鈕,text1會擷取焦點,邊框高亮,變成了可以輸入的狀態;而點擊triggerHandler按鈕,text2沒有任何反應,因為focus事件的預設行為被阻止了。特別注意:最開始我是使用<a>標籤的click事件進行測試的,因為超連結被點擊的事件預設行為就是跳到新的URL或者錨點。但測試結果是:使用trigger和triggerHandler表現都是一致的,都沒有開啟新的URL。原因是:由於瀏覽器中連結的安全性限制,jQuery對連結的預設行為都統一為不觸發,所以trigger不能觸發。
4. trigger和triggerHandler在觸發事件的時候都可以自訂參數,而方式一不行。
<script>$(function(){$("#btn").click(function(event, a, b){alert(a);alert(b);});// 普通的點擊事件時,a和b是undefined類型$("#btn").click();// trigger或triggerHandler,a是foo, b是bar$("#btn").trigger("click",["foo","b是bar"]);})</script><body><input type="button" id="btn" value="click"></body>
5. trigger和triggerHandler函數的返回值不同。這個不重要,實際開發中也沒有什麼意義。你可以結果JQuery的API文檔,自己寫代碼測試下。
6. trigger和triggerHandler都支援事件命名空間,在命名空間上的表現也完全一致。
什麼是事件命名空間?它有什麼作用?我在這篇部落格中有詳細的介紹。
<script>$(function(){$("#btn").bind("click",function(){alert("no");});$("#btn").bind("click.a",function(){alert("a");});$("#btn").bind("click.b",function(){alert("b");});// 列印no$("#btn").trigger("click!");// 列印no,a,b$("#btn").trigger("click");// 列印a$("#outA").trigger("click.a");// 無列印$("#outA").trigger(".a");})</script><body><input type="button" id="btn" value="click"></body>通過輸出結果,可以得出以下結論:
a) 可以在事件類型後面加上驚嘆號 ! 來只觸發那些沒有命名空間的事件處理函數。
b) trigger(".a")這種寫法不能觸發任何事件,不能像unbind一樣。
c) trigger("click.a")這種寫法可以觸發對應的事件處理函數。
d) trigger("click")觸發所有click類型的事件處理函數。