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則觸發所有物件的事件處理函式。
3. trigger會觸發事件的預設行為,triggerHandler則會阻止事件的預設行為。這一點上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>
<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型別的事件處理函式。