目錄
一、綁定事件
使用jQuery事件模型,可以利用bind() 方法在DOM元素上創建事件處理器。bind函數使用如下所示:
方法語法:bind
bind(eventType, data, hanlder)
bind(eventMap)
創建一個函數,將其作爲在匹配集中所有元素上指定的事件類型的事件處理器
參數
eventType (字符串)爲將要創建的處理器指定事件類型的名稱。可以使用空格分隔的列表指定多個事件類型
通過在事件名稱的後面添加圓點字符分隔的後綴,這些事件類型可以指定命名空間。本節的剩餘部分會對其進行詳細介紹
data (對象)調用者提供的數據,用來附加到Event 實例的data 屬性,以便爲處理器函數所使用。如果省略,可以指定第二個參數爲處理器函數
handler (函數)將要創建爲事件處理器的函數。當調用此函數時,會傳入Event 實例,並設置函數上下文(this )爲冒泡階段的當前元素
eventMap (對象)一個JavaScript對象,允許在一次調用中創建多個事件類型的處理器。屬性的名稱指定事件類型(與eventType 參數相同),屬性的值提供處理器
返回值
包裝集
- 舉例說明
/*
爲頁面上的每個圖片綁定提供內聯函數,作爲單擊事件處理器
*/
$('img').bind('click',function(event){alert('Hi there!');});
/*
對img圖片添加3個事件
*/
$('img').bind({
click: function(event) { /* handle clicks */ },
mouseenter: function(event) { /* handle mouseenters */ },
mouseleave: function(event) { /* handle mouseleaves */ }
});
爲了使開發者更加方便的綁定事件,JQuery封裝了常用的事件以便節約更多的代碼。我們稱它爲簡寫事件,見如下表格。
方法名 | 觸發條件 | 描述 |
---|---|---|
click(fn) | 鼠標 | 觸發每一個匹配元素的click(單擊)事件 |
dblclick(fn) | 鼠標 | 觸發每一個匹配元素的dblclick(雙擊)事件 |
mousedown(fn) | 鼠標 | 觸發每一個匹配元素的mousedown(點擊後)事件 |
mouseup(fn) | 鼠標 | 觸發每一個匹配元素的mouseup(點擊彈起)事件 |
mouseover(fn) | 鼠標 | 觸發每一個匹配元素的mouseover(鼠標移入)事件 |
mouseout(fn) | 鼠標 | 觸發每一個匹配元素的mouseout(鼠標移出)事件 |
mousemove(fn) | 鼠標 | 觸發每一個匹配元素的mousemove(鼠標移動)事件 |
mouseenter(fn) | 鼠標 | 觸發每一個匹配元素的mouseenter(鼠標穿過)事件 |
mouseleave(fn) | 鼠標 | 觸發每一個匹配元素的mouseleave(鼠標穿出)事件 |
keydown(fn) | 鍵盤 | 觸發每一個匹配元素的keydown(鍵盤按下)事件 |
keyup(fn) | 鍵盤 | 觸發每一個匹配元素的keyup(鍵盤按下彈起)事件 |
keypress(fn) | 鍵盤 | 觸發每一個匹配元素的keypress(鍵盤按下)事件 |
unload(fn) | 文檔 | 當卸載本頁面時綁定一個要執行的函數 |
resize(fn) | 文檔 | 觸發每一個匹配元素的resize(文檔改變大小)事件 |
scroll(fn) | 文檔 | 觸發每一個匹配元素的scroll(滾動條拖動)事件 |
focus(fn) | 表單 | 觸發每一個匹配元素的focus(焦點激活)事件 |
blur(fn) | 表單 | 觸發每一個匹配元素的blur(焦點丟失)事件 |
focusin(fn) | 表單 | 觸發每一個匹配元素的focusin(焦點激活)事件 |
focusout(fn) | 表單 | 觸發每一個匹配元素的focusout(焦點丟失)事件 |
select(fn) | 表單 | 觸發每一個匹配元素的select(文本選定)事件 |
change(fn) | 表單 | 觸發每一個匹配元素的change(值改變)事件 |
submit(fn) | 表單 | 觸發每一個匹配元素的submit(表單提交)事件 |
- 舉例說明
這裏封裝的大部分方法都比較好理解,我們沒必要一一演示確認,重點看幾個需要注意區分的簡寫方法。
.mouseover()和.mouseout()表示鼠標移入和移出的時候觸發。那麼JQuery還封裝了另外一組:.mouseenter()和.mouseleave()表示鼠標穿過與穿出的時候觸發。那麼這兩組本質上有什麼區別呢?手冊上的說明是:.mouseenter()和.mouseleave()這組穿過子元素不會觸發,而.mouseover()和.mouseout()則會觸發。
<!--HTML頁面設置-->
<div style="width:200px;height:200px;background:green;">
<p style="width:100px;height:100px;background:red;">
</div>
<strong></strong>
<script>
//mouseover移入
$('div').mouseover(function () {//移入div 會觸發,移入p 再觸發
$('strong').html(function (index, value) {
return value+'1';
});
});
//mouseenter穿過
$('div').mouseenter(function () {//穿過div 或者p
$('strong').html(function (index, value) {//在這個區域只觸發一次
return value+'1';
});
});
//mouseout移出
$('div').mouseout(function () { //移出p 會觸發,移出div 再觸發
$('strong').html(function (index, value) {
return value+'1';
});
});
//mouseleave穿出
$('div').mouseleave(function () {//移出整個div 區域觸發一次
$('strong').html(function (index, value) {
return value+'1';
});
});
.keydown()、.keyup()返回的是鍵碼,而.keypress()返回的是字符編碼。
$('input').keydown(function (e) {
alert(e.keyCode);//按下a 返回65
});
$('input').keypress(function (e) {
alert(e.charCode);//按下a 返回97
});
</script>
注意:e.keyCode和e.charCode在兩種事件互換也會產生不同的效果,除了字符還有一些非字符鍵的區別。
.focus()和.blur()分別表示光標激活和丟失,事件觸發時機是當前元素。而.focusin()和.focusout()也表示光標激活和丟失,但事件觸發時機可以是子元素。
<!--HTML部分-->
<div style="width:200px;height:200px;background:red;">
<input type="text" value="" />
</div>
<strong></strong>
<script>
//focus光標激活
$('input').focus(function () {//當前元素觸發
$('strong').html('123');
});
//focusin光標激活
$('div').focusin(function () {//綁定的是div 元素,子類input 觸發
$('strong').html('123');
});
</script>
注意:.blur()和.focusout()表示光標丟失,和激活類似,一個必須當前元素觸發,另一個可以是子元素觸發。
JQuery提供了許多最常用的事件效果,組合一些功能實現了一些複合事件,比如切換功能、智能加載等。
方法名 | 描述 |
---|---|
ready(fn) | 當DOM加載完畢觸發事件 |
hover([fn1,]fn2) | 當鼠標移入觸發第一個fn1,移出觸發fn2 |
toggle(fn1,fn2[,fn3..]) | 已廢棄,當鼠標點擊觸發fn1,再點擊觸發fn2... |
- 舉例說明
//背景移入移出切換效果
$('div').hover(function () {
$(this).css('background', 'black');//mouseenter 效果
}, function () {
$(this).css('background', 'red');//mouseleave 效果,可省略
});
注意:.hover()方法是結合了.mouseenter()方法和.mouseleva()方法,並非.mouseover()和.mouseout()方法。
.toggle()這個方法比較特殊,這個方法有兩層含義:第一層含義就是已經被1.8版廢用、1.9版刪除的用法,也就是點擊切換複合事件的用法;第二層含我將會在動畫那章講解到。既然廢棄掉了,就不應該使用。被刪除的原因是:以減少混亂和提高潛在的模塊化程度。但你又非常想用這個方法,並且不想自己編寫類似的功能,可以下載jquery-migrate.js文件,來向下兼容已被刪除掉的方法。
//背景點擊切換效果(1.9 版刪除了)
<script type="text/javascript" src="jquery-migrate-1.2.1.js"></script>
$('div').toggle(function () {//第一次點擊切換
$(this).css('background', 'black');
}, function () {//第二次點擊切換
$(this).css('background', 'blue');
}, function () {//第三次點擊切換
$(this).css('background', 'red');
});
/*
注意:由於官方已經刪除掉這個方法,所以也是不推薦使用的,
如果在不基於向下兼容的插件JS。我們可以自己實現這個功能。
*/
var flag = 1;//計數器
$('div').click(function () {
if (flag == 1) {//第一次點擊
$(this).css('background', 'black');
flag = 2;
} else if (flag == 2) {//第二次點擊
$(this).css('background', 'blue');
flag = 3
} else if (flag == 3) {//第三次點擊
$(this).css('background', 'red');
flag = 1
}
});
二、解綁事件
jQuery爲事件處理提供了額外功能,就是通過指定命名空間來對事件處理器進行分組。和常規的命名空間不同(通過前綴指定命名空間),它通過爲事件名稱添加以圓點分隔的後綴來指定命名空間。事實上,如果你願意,可以使用多個後綴將事件歸入多個命名空間。
通過這種方式對事件綁定進行分組,隨後就可以將它們看作一個單元以便對其進行操作。
例如,一個頁面有兩種模式:顯示模式和編輯模式。在編輯模式下,事件監聽器放置在頁面的許多元素上,但是在顯示模式下這些監聽器都不適用了,因此當頁面離開編輯模式時,就需要刪除這些監聽器。我們可以爲編輯模式下的事件指定命名空間,代碼如下所示:
$('#thing1').bind('click.editMode',someListener);
$('#thing2').bind('click.editMode',someOtherListener);
//當頁面離開編輯模式需要刪除所有的綁定時
$('*').unbind('click.editMode');
方法語法:unbind
unbind(eventType, listener)
unbind(event)
爲包裝集中的所有元素刪除由可選的傳入參數指定的事件處理器。如果沒有提供參數,則會從元素上刪除所有的監聽器
參數
eventType (字符串)如果提供,則只刪除爲指定事件類型創建的監聽器
listener (函數)如果提供,則找出將要刪除的指定監聽器
Event (事件)刪除觸發Event 實例描述的事件的監聽器
返回值
包裝集
三、事件對象
事件對象就是event對象,通過處理函數默認傳遞接受。之前處理函數的e就是event事件對象,event對象有很多可用的屬性和方法,如下實例:
//通過處理函數傳遞事件對象
$('input').bind('click', function (e) { //接受事件對象參數
alert(e);
});
屬性名 | 描述 |
---|---|
type | 獲取這個事件的事件類型,如click |
target | 獲取綁定事件的DOM元素 |
data | 獲取事件調用時的額外數據 |
relatedTarget | 獲取移入移出目標點離開或進入的那個DOM元素 |
currentTarget | 獲取冒泡前觸發的DOM元素,等同於this |
pageX,pageY | 獲取相對於頁面原點的水平/垂直座標 |
screenX,screenY | 獲取顯示器屏幕位置的水平/垂直座標(非JQuery封裝) |
clientX,clientY | 獲取相對於頁面視口的水平/垂直座標(非JQuery封裝) |
result | 從前面的事件處理器返回的最近的非undefined 的值 |
timeStamp | 獲取事件觸發的時間戳 |
which | 對於鍵盤事件,指定觸發事件的按鍵的數字代碼;對於鼠標事件,指定按下的是哪個按鈕(1 爲左鍵、2 爲中鍵、3 爲右鍵)。應該使用which 屬性代替button 屬性,因爲不能保證跨瀏覽器button 屬性的一致性 |
altKey | 當觸發事件時,如果Alt鍵已被按下,則設置爲true ,否則爲false 。在大部分的Mac鍵盤中Alt鍵標記爲Option |
ctrlKey | 當觸發事件時,如果Ctrl鍵已被按下,則設置爲true ,否則爲false |
metaKey | 當觸發事件時,如果Meta鍵已被按下,則設置爲true ,否則爲false 。在PC上Meta鍵是Ctrl鍵,而在Mac上是Command鍵 |
shiftKey | 當觸發事件時,如果Shift鍵已被按下,則設置爲true ,否則爲false |
- 舉例說明
//通過event.type 屬性獲取觸發事件名
$('input').click(function (e) {
alert(e.type);
});
//通過event.target 獲取綁定的DOM 元素
$('input').click(function (e) {
alert(e.target);
});
//通過event.data 獲取額外數據,可以是數字、字符串、數組、對象
$('input').bind('click', 123, function () {//傳遞data 數據
alert(e.data);//獲取數字數據
);
注意:如果字符串就傳遞:'123',如果是數組就傳遞:[123,'abc'],如果是對象就傳遞:
{user: 'Lee', age: 100}。數組的調用方式是:e.data[1],對象的調用方式是:e.data.user。
//event.data獲取額外數據,對於封裝的簡寫事件也可以使用
$('input').click({user: 'Lee', age: 100},function (e) {
alert(e.data.user);
});
注意:鍵值對的鍵可以加上引號,也可以不加;在調用的時候也可以使用數組的方式:
alert(e.data['user']);
//獲取移入到div 之前的那個DOM 元素
$('div').mouseover(function (e) {
alert(e.relatedTarget);
});
//獲取移出div 之後到達最近的那個DOM 元素
$('div').mouseout(function (e) {
alert(e.relatedTarget);
});
//獲取綁定的那個DOM 元素,相當於this,區別於event.target
$('div').click(function (e) {
alert(e.currentTarget);
});
注意:event.target得到的是觸發元素的DOM,event.currentTarget得到的是監聽元素的DOM。而this也是得到監聽元素的DOM。
//獲取上一次事件的返回值
$('div').click(function (e) {
return '123';
});
$('div').click(function (e) {
alert(e.result);
});
//獲取當前的時間戳
$('div').click(function (e) {
alert(e.timeStamp);
});
//獲取鼠標的左中右鍵
$('div').mousedown(function (e) {
alert(e.which);
});
//獲取鍵盤的按鍵
$('input').keyup(function (e) {
alert(e.which);
});
//獲取是否按下了ctrl 鍵,meta 鍵不存在,導致無法使用
$('input').click(function (e) {
alert(e.ctrlKey);
});
//獲取觸發元素鼠標當前的位置
$(document).click(function (e) {
alert(e.screenY+ ',' + e.pageY + ',' + e.clientY);
});
方法 | 描述 |
---|---|
preventDefault() | 阻止任意默認的語義動作(比如表單提交、鏈接重定向、複選框狀態的改變等)發生 |
stopPropagation() | 停止事件沿着DOM樹向上進一步傳播。當前目標元素上附加的事件不受影響。不僅支持瀏覽器定義的事件,而且支持自定義事件 |
stopImmediatePropagation() | 停止所有事件的進一步傳播,包括附加在當前目標元素上的事件 |
isDefaultPrevented() | 如果已經在此實例上調用了preventDefault() 方法,則返回true |
isPropagationStopped() | 如果已經在此實例上調用了stopPropagation() 方法,則返回true |
isImmediatePropagationStopped() | 如果已經在此實例上調用了stopImmediatePropagation() 方法,則返回true |
四、高級事件
在事件觸發的時候,有時我們需要一些模擬用戶行爲的操作。例如,當網頁加載完畢後自行點擊一個按鈕觸發一個事件,而不是由用戶去點擊。
//點擊按鈕事件
$('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']);
注意:當傳遞一個值的時候,直接傳遞即可。當兩個值以上時,需要在前後用中括號包含起來。但不能認爲是數組形式,下面給出一個複雜的說明。
$('input').click(function (e, data1, data2) {
alert(data1.a + ',' + data2[1]);
}).trigger('click', [{'a': '1', 'b': '2'}, ['123','456']]);
除了通過JavaScript事件名觸發,也可以通過自定義的事件觸發。所謂自定義事件,其實就是一個被.bind()綁定的任意函數。
$('input').bind('myEvent', function () {
alert('自定義事件!');
}).trigger('myEvent');
.trigger()方法提供了簡寫方案,只要想讓某個事件執行模擬用戶行爲,直接再調用一個空的同名事件即可。
$('input').click(function () {
alert('我的第一次點擊來自模擬!');
}).click();//空的click()執行的是trigger()
這種便捷的方法,JQuery幾乎所有常用的事件都提供了。
blur | focusin | mousedown | resize |
change | focusout | mousenter | 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');
在常規的使用情況下,兩者幾乎沒有區別,都是模擬用戶行爲,也可以傳遞額外參數。但在某些特殊情況下,就產生了差異:
(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 返回
(4)trigger()在創建事件的時候,會冒泡。但這種冒泡是自定義事件才能體現出來,是JQuery擴展於DOM的機制,並非DOM特性。而.triggerHandler()不會冒泡。
jQuery提供了我們所期望的live() 方法,該方法允許預先爲那些還不存在的元素創建事件處理器。live() 的語法如下。
方法語法:live
live(eventType, data, listener)
當指定類型的事件在元素(任何用來創建包裝集的與選擇器相匹配的元素)上發生時,會將傳入的監聽器作爲處理器調用,而無論在調用live 方法時這些元素是否已經存在
參數
eventType (字符串)指定處理器將要調用的事件類型的名稱。和bind() 不同,不能指定空格分隔的事件類型列表3
3 這個說法不對,從jQuery1.4開始已經可以爲live() 方法的第一個參數指定空格分隔的事件類型列表或者自定義事件類型了。
data (對象)調用者提供的數據,用來附加到Event 實例的data 屬性,以便爲處理器函數所使用。如果省略,可以指定第二個參數爲處理器函數
listener (函數)將要作爲事件處理器被調用的函數。當調用此函數時,會向此函數傳入Event實例,並設置目標元素爲函數上下文(this )
返回值
包裝集
如果這個方法的語法讓你想起bind() 方法的語法,那就對了。這個方法的定義和行爲與bind() 很相似。不同之處是,當相應的事件發生時,該方法會爲所有匹配選擇器的元素觸發此事件,甚至包括那些在調用live() 的時候還不存在的元素。
$('div.attendToMe').live(
'click',
function(event){ alert(this); }
);
在頁面的整個生命週期內,單擊任意擁有類attendToMe 的<div> 元素都會調用事件處理器並傳入一個事件實例。而且前面的代碼不需要放置於就緒處理器中,因爲“live”事件不關心DOM是否已經存在。
利用live() 方法,可以非常容易地在頁面上的某個地方創建需要的事件處理器,而無需擔心元素是否已經存在,或者什麼時候創建元素。
但是使用live() 時必須要遵守一些注意事項。因爲它和bind() 很相似,你可能會期望“live”事件完全按照與原生事件相同的方式工作,但是它們是有差異的,在某些頁面中這種差異可能很重要,也可能無關緊要。
首先,要意識到“live”事件不是 原生的“普通”事件。當類似於單擊的事件發生時,它會沿着DOM元素向上傳播(如前所述),並調用每一個已經創建的事件處理器。一旦事件到達用來創建包裝集的上下文,也就是調用live() 的地方(通常是文檔根節點4 ),上下文會在子節點中檢查匹配“live”選擇器的元素5 。“live”事件處理器會在每個匹配的元素上觸發,並且這個已觸發的事件不能 繼續傳播。
方法語法:die
die(eventType, listener)
刪除由live() 創建的“live”事件處理器,並且阻止在將來創建的元素上調用處理器,這些元素是與調用live() 時使用的選擇器相匹配的元素
參數
eventType (字符串)如果提供,則只刪除爲指定事件類型創建的監聽器
listener (函數)如果提供,則找出將要刪除的指定監聽器
返回值
包裝集