1. 程式人生 > >JQuery手動觸發事件API之:通過程式碼看清trigger與triggerHandler的差別

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型別的事件處理函式。