首页 > 代码库 > 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=http://www.mamicode.com/"trigger" tabIndex="2">>

点击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=http://www.mamicode.com/"click">>


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=http://www.mamicode.com/"click">>通过输出结果,可以得出以下结论:

a) 可以在事件类型后面加上感叹号 ! 来只触发那些没有命名空间的事件处理函数。

b) trigger(".a")这种写法不能触发任何事件,不能像unbind一样。

c) trigger("click.a")这种写法可以触发对应的事件处理函数。

d) trigger("click")触发所有click类型的事件处理函数。


JQuery手动触发事件API之:通过代码看清trigger与triggerHandler的差别