內容提綱:
1.模擬操作
2.命名空間
3.事件委托
4.on、off 和 one
發文不易,轉載請注明出處!
一.模擬操作
在事件觸發的時候,有時我們需要一些模擬用戶行為的操作。例如:當網頁加載完畢后自行點擊一個按鈕觸發一個事件,而不是用戶去點擊。
//點擊按鈕事件
$('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', ['abc', '123']);
PS:當傳遞一個值的時候,直接傳遞即可。當兩個值以上,需要在前后用中括號包含起來。但不能認為是數組形式,下面給出一個復雜的說明:
$('input').click(function (e, data1, data2) {
alert(data1.a + ',' + data2[1]);
}).trigger('click', [{'a' : '1', 'b' : '2'}, ['123','456']]);
除了通過 JavaScript 事件名觸發,也可以用於自定義的事件觸發,所謂自定義事件其實就是一個被.bind()綁定的任意函數。自定義事件無法單獨執行,但是可以通過trigger模擬執行。示例如下:
$('input').bind('myEvent', function () {
alert('自定義事件!');
}).trigger('myEvent');
.trigger()方法提供了簡寫方案,只要想讓某個事件執行模擬用戶行為,直接再調用一個空的同名事件即可。
$('input').click(function () {
alert('我的第一次點擊來自模擬!');
}).click(); //執行空的click()模擬用戶行為
這種便捷的方法,jQuery 幾乎個所有常用的事件都提供了。
jQuery 還提供了另外一個模擬用戶行為的方法:.triggerHandler();這個方法的使用和.trigger()方法一樣。
$('input').click(function () {
alert('我的第一次點擊來自模擬!');
}).triggerHandler('click');
在常規的使用情況下,與trigger()幾乎沒有區別,都是模擬用戶行為,也可以傳遞額外參數。但在某些特殊情況下仍有差異,主要有以下四點:
1. .triggerHandler()方法並不會觸發事件的默認行為,而.trigger()會。
$('form').trigger('submit'); //模擬用戶執行提交,並跳轉到執行頁面
$('form').triggerHandler('submit'); //模擬用戶執行提交,並阻止的默認行為
如果我們希望使用.trigger()來模擬用戶提交, 並且阻止事件的默認行為, 則需要這么寫:
$('form').submit(function (e) {
e.preventDefault(); //阻止默認行為
}).trigger('submit');
2. .triggerHandler()方法只會影響第一個匹配到的元素,而.trigger()會影響所有。
3. .triggerHandler()方法會返回當前事件執行的返回值,如果沒有返回值,則返回undefined;而.trigger()則返回當前包含事件觸發元素的 jQuery 對象(方便連綴調用)。
alert($('input').click(function () {
return 123;
}).triggerHandler('click')); //返回 123,沒有 return 返回undefined
4. .trigger()在創建事件的時候,會冒泡。但這種冒泡是自定義事件才能體現出來,是jQuery 擴展於 DOM 的機制,並非 DOM 特性。而.triggerHandler()不會冒泡。
示例:
html部分代碼:
1 <div class="d1"> 2 3 <div class="d2"> 4 5 <div class="d3"> 6 7 div 8 9 </div> 10 11 </div> 12 13 </div>
JS代碼部分:
1 $('div').bind('myEvent', function () { 2 3 alert('自定義事件!'); 4 5 }) 6 7 8 $('.d3').trigger('myEvent'); //會冒泡,有3個輸出 9 10 11 $('div').bind('myEvent', function () { 12 13 alert('自定義事件!'); 14 15 }) 16 17 18 $('.d3').triggerHandler('myEvent'); //不會冒泡,只有1個輸出
二.命名空間
有時,我們想對事件進行移除。但對於同名同元素綁定的事件移除往往比較麻煩,這個時候,可以使用事件的命名空間解決。
$('input').bind('click.abc', function () {
alert('abc');
});
$('input').bind('click.xyz', function () {
alert('xyz');
});
$('input').unbind('click.abc'); //移除 命名為abc的click 事件
PS:也可以直接使用('.abc'),這樣的話,可以移除相同命名空間的不同事件。對於模擬操作.trigger()和.triggerHandler(),用法也是一樣的。
$('input').trigger('click.abc');
三.事件委托
//HTML 代碼部分
1 <div style="background:red;width:200px;height:200px;" id="box"> 2 <input type="button" value="按鈕" class="button" /> 3 </div> 4 5
//使用.bind()不具備動態綁定功能,只有點擊原始按鈕才能生成
$('.button').bind('click', function () {
$(this).clone().appendTo('#box');
});
//使用.live()具備動態綁定功能,jQuery1.3 使用,jQuery1.7 之后廢棄,jQuery1.9 刪除。
$('.button').live('click', function () {
$(this).clone().appendTo('#box');
});
PS:.live()原理就是把 click 事件綁定到祖先元素$(document)上,而只需要給$(document)綁定一次即可,而非多次。然后就可以處理后續動態加載的按鈕的單擊事件。在接受任何事件時,$(document)對象都會檢查事件類型(event.type)和事件目標(event.target),如果 click事件是.button,那么就執行委托給它的處理程序。1.9版本之后.live()方法已經被刪除,無法使用了。需要測試使用的話,需要引入向下兼容插件。
//.live()無法使用鏈接連綴調用,因為參數的特性導致
$('#box').children(0).live('click', function () {
$(this).clone().appendTo('#box');
});
在上面的例子中,我們使用了.clone()克隆。其實如果想把事件行為復制過來,我們只需要傳遞 true 即可:.clone(true)。這樣也能實現類似事件委托的功能,但原理卻截然不同。一個是復制事件行為,一個是事件委托。而在非克隆操作下,此類功能只能使用事件委托。如下:
$('.button').live('click', function () {
$('<input type="button" value="復制的" class="button" />').appendTo('#box');
});
當我們需要停止事件委托的時候,可以使用.die()來取消掉。
$('.button').die('click');
由於.live()和.die()在 jQuery1.4.3 版本中廢棄了, 之后推出語義清晰、 減少冒泡傳播層次、又支持連綴調用方式的方法: .delegate()和.undelegate()。 但這個方法在 jQuery1.7 版本中被.on()方法整合替代了。
$('#box').delegate('.button', 'click', function () { //注意綁定的元素和參數的順序
$(this).clone().appendTo('#box');
});
$('#box').undelegate('.button','click');
//支持連綴調用方式
$('div').first().delegate('.button', 'click', function () {
$(this).clone().appendTo('div:first');
});
PS:.delegate()需要指定父元素,然后第一個參數是當前元素,第二個參數是事件方式, 第三個參數是執行函數。 和.bind()方法一樣, 可以傳遞額外參數。 .undelegate()和.unbind()方法一樣可以直接刪除所有事件,比如:.undelegate('click')。也可以刪除命名空間的事件,比如:.undelegate('click.abc')。
PS:.live()和.delegate()和.bind()方法一樣都是事件綁定,那么區別也很明顯,用途上遵循兩個規則:1.在 DOM 中很多元素綁定相同事件時;2.在 DOM 中尚不存在即將生成的元素綁定事件時;我們推薦使用事件委托的綁定方式,否則推薦使用.bind()的普通綁定。
四.on、off 和 one
目前綁定事件和解綁的方法有三組共六個。由於這三組的共存可能會造成一定的混亂,為此 jQuery1.7版本以后推出了.on()和.off()方法徹底摒棄前面三組。
//替代.bind()方式
$('.button').on('click', function () {
alert('替代.bind()');
});
//替代.bind()方式,並使用額外數據和事件對象
$('.button').on('click', {user : 'Lee'}, function (e) {
alert('替代.bind()' + e.data.user);
});
//替代.bind()方式,並綁定多個事件
$('.button').on('mouseover mouseout', function () {
alert('替代.bind()移入移出!');
});
//替代.bind()方式,以對象模式綁定多個事件
$('.button').on({
mouseover : function () {
alert('替代.bind()移入!');
},
mouseout : function () {
alert('替代.bind()移出!');
}
});
//替代.bind()方式,阻止默認行為並取消冒泡
$('form').on('submit', function () {
return false;
});
或
$('form').on('submit', false); //直接傳遞false參數
//替代.bind()方式,阻止默認行為
$('form').on('submit', function (e) {
e.preventDefault();
});
//替代.bind()方式,取消冒泡
$('form').on('submit', function (e) {
e.stopPropagation();
});
//替代.unbind()方式,移除事件
$('.button').off('click');
$('.button').off('click', fn);
$('.button').off('click.abc');
//替代.live()和.delegate(),事件委托
$('#box').on('click', '.button', function () {
$(this).clone().appendTo('#box');
});
//替代.die()和.undelegate(),取消事件委托
$('#box').off('click', '.button');
注意:和之前方式一樣,事件委托和取消事件委托也有各種搭配方式,比如額外數據、命名空間等等,這里不在贅述。
不管是.bind()還是.on(),綁定事件后都不是自動移除事件的,需要通過.unbind()和.off()來手工移除。jQuery 提供了.one()方法,綁定元素執行完畢后自動移除事件,可以方法僅觸發一次的事件。
//類似於.bind()只觸發一次
$('.button').one('click', function () {
alert('one 僅觸發一次!');
});
//類似於.delegate()只觸發一次
$('#box).one('.button', 'click', function () {
alert('one 僅觸發一次!');
});
For my lover,
and thank you Mr.Lee!