高级事件(一)
jQuery不但封装了大量常用的事件处理,还提供了不少高级事件方便开发者使用。比如模拟用户触发事件、事件委托事件、和统一整合的on和off,以及仅执行一次的one方法。这些方法大大降低了开发者难度,提升了开发者的开发体验。
模拟操作
在事件触发的时候,有时我们需要一些模拟用户行为的操作。例如:当网页加载完毕后自行点击一个按钮触发一个事件,而不是用户去点击。
html(部分)代码:
<input type="button" value="按钮" />
jQuery代码:
//点击按钮事件 $("input").click(function() { alert("我将要使用模拟用户操作来触发!"); }); //模拟用户点击操作 $("input").trigger("click");
也可以合并两个方法:
$("input").click(function() { alert("我将要使用模拟用户操作来触发!"); }).trigger("click");
有时在模拟用户行为的时候,我们需要给事件执行传递参数,这个参数类似与event.data的额外数据,可以是数字、字符串、数组、对象。
如:
$("input").click(function(e,data1,data2) { alert(data1 + "|" + data2); }).trigger("click",["123","abc"]);
注意:trigger额外数据,只有一条的时候,可以省略中括号,多条不能省略,第二条之后就无法识别了。如:
$("input").click(function(e,data1,data2) { alert(data1 + "|" + data2); // 123|undefined }).trigger("click","123","abc");
注意:当传递一个值的时候,直接传递即可。当两个值以上,需要在前后用中括号包含起来。但不能认为是数组形式,下面给出一个复杂的说明。
$("input").click(function(e,data1,data2,data3,data4) { alert(data1 + "|" + data2 + "|" +data3[1] + "|" + data4.user); }).trigger("click",["123","abc",["a","b","c"],{user:"Lee"}]);
注意:通过event.data获取额外数据。
$("input").bind("click", {user:'Lee'}, function(e,data1,data2,data3,data4) { alert(data1 + "|" + data2 + "|" +data3[1] + "|" + data4.user +"|" + e.data.user); }).trigger("click",["123","abc",["a","b","c"],{user:"Lee"}]);
除了通过JavaScript事件名触发,也可以通过自定义的事件触发,所谓自定义事件其实就是一个被.bind()绑定的任意函数。
//click,mouseover这些系统事件,自定义事件就是自己起名字的事件 $("input").bind("myEvent", function() { alert("自定义事件"); }).trigger("myEvent");
.trigger()方法提供了简写方案,只要想让某个事件执行模拟用户行为,直接再调用一个空的同名事件即可。
$("input").click(function() { alert("我将要使用模拟用户操作来触发!"); }).click(); //空的click()执行的是trigger()
这种便捷的方法,jQuery几乎所有常用的事件都提供了。
blur | focusin | mousedown | resize |
change | focusout | mouseenter | scroll |
click | keydown | mouseleave | select |
dblclick | keypress | mousemove | submit |
error | keyup | mouseout | unload |
focus | load | mouseover |
jQuery还提供了另外一个模拟用户行为的方法:.triggerHandler();这个方法的使用和.trigger()方法一样。
$("input").click(function() { alert("我将要使用模拟用户操作来触发!"); }).triggerHandler("click");
在常规的使用情况下,两者几乎没有区别,都是模拟用户行为,也可以传递额外参数。但在某些特殊情况下,就产生了差异:
①.triggerHandler()方法并不会触发事件的默认行为,而.trigger()会。
html(部分)代码:
<form action="123.html"> <input type="submit" value="按钮" /> </form>
jQuery代码如下:
//trigger提交后跳转,没有阻止默认行为 $("form").trigger("submit"); //模拟用户执行提交,并跳转到执行页面 //trigger提交后没有跳转,默认行为被阻止 $("form").triggerHandler("submit"); //模拟用户执行提交,并阻止的默认行为
如果我们希望使用.trigger()来模拟用户提交,并且阻止事件的默认行为,则需要这么写:
$("form").submit(function(e) { e.preventDefault(); //阻止默认行为 }).trigger("submit");
②.triggerHandler()方法只会影响第一个匹配到的元素,而.trigger()会影响所有。
html(部分)代码如下:
<input type="button" value="按钮" /> <input type="button" value="按钮" /> <input type="button" value="按钮" />
jQuery代码:
$("input").click(function() { alert("我将要使用模拟用户操作来触发!"); }).click();
或
$("input").click(function() { alert("我将要使用模拟用户操作来触发!"); }).trigger("click");
以上两句代码等价,而且会影响到所有的元素,即会弹出3个对话框。
再看jQuery代码:
$("input").click(function() { alert("我将要使用模拟用户操作来触发!"); }).triggerHandler("click");
以上代码只会影响第一个匹配到的元素,即只会弹出一个对话框。
③.triggerHandler()方法会返回当前事件执行的返回值,如果没有返回值,则返回undefined;而.trigger()则返回当前包含事件触发元素的jQuery对象(方便链式连缀调用)。
html(部分)代码:
<input type="button" value="按钮" />
jQuery代码如下:
alert($("input").click(function() { alert("我将要使用模拟用户操作来触发!"); }).trigger("click")); //[object Object]
.trigger()返回当前包含事件触发元素的jQuery对象(方便链式连缀调用):
$("input").click(function() { alert("我将要使用模拟用户操作来触发!"); }).trigger("click").css("color", "red"); //返回jQuery对象,可以连缀
alert($("input").click(function() { alert("我将要使用模拟用户操作来触发!"); return 123; }).triggerHandler("click")); //返回123,没有return返回undefined
所以.triggerHandler()是不能链式连缀调用的:
$("input").click(function() { alert("我将要使用模拟用户操作来触发!"); return 123; }).triggerHandler("click").css("color", "red"); //返回return值,或undefined
④.trigger()在创建事件的时候,会冒泡,但这种冒泡是自定义事件才能体现出来,是jQuery扩展于DOM的机制,并非DOM特性,而.triggerHandler()不会冒泡。
html(部分)代码如下:
<div class="d1"> <div class="d2"> <div class="d3"> div </div> </div> </div>
jQuery代码:
$("div").bind("myEvent", function() { alert("自定义事件"); }); $(".d3").trigger("myEvent");//会冒泡
$("div").bind("myEvent", function() { alert("自定义事件"); }); $(".d3").triggerHandler("myEvent");//不会冒泡
命名空间
有时,我们想对事件进行移除。但对于同名同元素绑定的事件移除往往比较麻烦,这个时候,可以使用事件的命名空间解决。
以前的做法:
$("input").bind("click", function() { alert("abc"); }); $("input").bind("click", function() { alert("xyz"); }); $("input").unbind("click"); //这样会将click事件移除
此刻的做法:
$("input").bind("click.abc", function() { alert("abc"); }); $("input").bind("click.xyz", function() { alert("xyz"); }); $("input").bind("mouseover.abc", function() { alert("abc"); }); $("input").unbind("click.abc"); //移除click事件中命名空间为abc的
注意:也可以直接使用('.abc'),这样的话,可以移除相同命名空间的不同事件。对于模拟操作.trigger()和.triggerHandler(),用法也是一样的。
$("input").unbind(".abc");
$("input").trigger("click.abc"); //只弹出abc的对话框