jQuery - 事件處理
事件處理
事件處理是網頁互動行為很重要的核心,通常當一個事件發生時,會去呼叫一個事件處理程序(event handler)的回呼函式,也就是事件發生時要做的事情。jQuery 對事件有許多特別的貼心設定。
事件觸發
要觸發一個事件要有三個步驟,第一個是指定選取對象
、第二個是指派事件
、第三個是傳遞一個函式
,在語意上是誰、在甚麼時候、做了甚麼事情,事件觸發有下列兩種方式。
一、使用事件名稱直接觸發
此方法為便捷方式,是方法二的捷徑,但只能夠用在 DOM 元素已經存在時有作用,在網頁讀取完畢時,若 DOM 元素還不存在,也就是後來產生的 DOM 元素,無法使用。
$('#myElement').click(function () { |
不帶參數直接呼叫事件。
$('button').click() |
二、使用 on()方法觸發
建議使用這種方式,on 方法提供了事件處理程序所有功能,而且語意上與 JavaScript 的 addEventListener() 相似,其實,on 是以 addEventListener 實作,且第三個參數是 false,也就是 jQuery 事件是以「事件冒泡」來實作,而不是「事件捕獲」,這很符合 JavaScript addEventListener 第三參數 useCapture 的預設 false。該方法又分為「直接綁定」與「委派綁定」。
.on(events [, selector ] [, data ], handler)
- events 可以多個事件,空格分隔事件名稱。
- 指定 css selector 為委派綁定,參考下方。
- 指定 data(可以任何資料類型),當事件發生時將通過 event.data 傳遞。
請忘記 bind() 與 live(),on() 都可以做到。
直接綁定
當 selector 省略或是 null,事件處理程序稱為直接綁定,會發生在選定的元素上,也就是呼叫該事件的元素。
$('#myElement').on('click', function () { |
委派綁定
又稱為事件委派(delegation),當提供 selector 參數時,事件處理程序稱為委派綁定。事件不被綁定元素所使用,而只對綁定元素的後代 selector 使用,委派事件綁定的優勢在於可以處理來自後代元素的事件,也就是程式後來產生的後代 DOM 元素。
委託事件處理程序不適用於SVG。
多事件觸發
on 可以使用多種事件觸發,以下 click,keypress 都會觸發不具名函式:
$(document).on('click keypress', function () { |
移除事件
可以使用 off() 來移除事件,要移除元素的所有事件,不要傳任何參數給 off()函式,這是殺傷力很強的方式,大部分情況下不會移除元素所有的事件處理程序。
$('input[type="submit"]').off() |
也可以指定移除的事件。
$('h1').each(function () { |
named space 命名空間移除特定目標的事件,可以為事件命名一個名字,這樣移除時可以指定該名稱。
$('#box').on('click.main', function () { |
事件類型
分類 | 事件名稱 |
---|---|
鍵 盤 | keydown,keyup,keypress |
滑 鼠 | click,dblclick,hover,mousedown,mouseenter,mouseleave,mouseup,,mousemove,mouseout,mouseover,toggle |
表 單 | blur,change,focus,focusin,focusout,select,submit,reset |
瀏 覽 器 | error,resize,scroll |
文 件 | load,unload,ready |
載入事件
名稱 | 常用 | 說明 |
---|---|---|
.ready() | DOM 載入完成後(不等待其他資源載入),ready 就觸發 |
瀏覽器事件(Browser Events)
與瀏覽器事件有關的設定 | 說明 |
---|---|
.resize() | 設定瀏覽器視窗大小改變時執行的處理 |
.scroll() | 設定瀏覽器視窗被捲動時執行的處理 |
滑鼠事件(Mouse Events)
與滑鼠動作有關的設定 | 說明 |
---|---|
.click() | 設定元素被點擊時執行的處理 |
.dblclick() | 設定元素被滑鼠雙擊時執行的處理 |
.hover() | 設定元素移入、移出時執行的處理 |
.mouseover() | 設定滑鼠停在元素上時執行的處理 |
.mouseout() | 設定滑鼠移出元素上時執行的處理 |
.mouseenter() | 設定滑鼠停在元素上時執行的處理 (包含範圍內的子元素) |
.mouseleave() | 設定滑鼠移出元素上時執行的處理 (包含範圍內的子元素) |
.mousedown() | 設定元素被按下時執行的處理 |
.mousemove() | 設定滑鼠在元素上方移動時執行的處理 |
.mouseup() | 設定滑鼠離開元素上方時執行的處理 |
## 表單事件(Form Events)
與表單事件有關的設定。 | 說明 |
---|---|
.change() | 當表單元素內容改變時執行的處理 |
.focus() | 當表單元素取得焦點時執行的處理 |
.focusin() | 當表單元素取得焦點時執行的處理 (包含子元素) |
.blur() | 當焦點離開表單元素時執行的處理 |
.focusout() | 當焦點離開表單元素時執行的處理 (包含子元素) |
.select() | 表單元素的值被選取時執行的處理 |
.submit() | 送出表單資料時執行的處理 |
鍵盤事件(Keyboard Events)
與鍵盤輸入有關的設定 | 說明 |
---|---|
.keydown() | 按下鍵盤按鈕時執行的處理 |
.keypress() | 鍵盤輸入時執行的處理 |
.keyup() | 放開鍵盤按鈕時執行的處理 |
事件應用
hover 事件
hover 是常使用的滑鼠事件,它是由 mouseenter 與 mouseleave 來實作,可由 e.type 確認,它可以傳入兩個匿名函式分別給 mouseenter 與 mouseleave 使用。如果只傳入一個引數給 hover(),那個函式會同時被用作 mouseenter 與 mouseleave 事件的處理器。
.hover(handlerIn, handlerOut)
$('a').hover( |
兩種滑鼠移入、移出的操作,第一種說明了 on 也可以物件實字來操作多種事件。
// 第一種用 on 並傳入一個選項物件 |
事件物件
事件物件(event object),當一個或多集合 jQuery 物件觸發事件時,會記錄著該物件包含與該次事件有關的資訊屬性與方法,被稱為事件物件(Event Object),它會被帶入第一參數,通常以 e 作為參數名稱。事件物件主要基於 W3C 的標準,也結合了業界的事件標準,jQuery 從原生的 JavaScript Event 物件中複製了常用屬性到每個 jQuery Event 物件中,因此屬性、方法名稱一樣,但對某些特定事件類型來說,其中部分屬性的值會是 undefined。
$(document).on('click', function (e) { |
e.target
event.target 屬性即實際被點擊的元素,可以記為最深處的目標,儲存著發生事件的目標元素,透過這個屬性可以確定 DOM 中首先接收到事件的元素。而且,this 引用的是處理事件的 DOM 元素,藉由 event.target 與 this 比對,可以做出以下的判斷。
$('#switcher').click(function (event) { |
或者是當 event.target 是 a 時忽略。
if ($(event.target).is('a')) return // 忽略發生於連結上的事件 |
e.currentTarget
currentTarget 屬性指出哪個元素註冊了事件,永遠與 this 相同
。如果 target 與 currentTarget 不同,表示所處理的事件就是自其發生處產生氣泡上浮後的事件,可以透過 is()方法來測試 target 元素。
e.relatedTarget
對於 mouseout 事件,它指向被進入的元素,對於 mouseover 事件,它指向被離開的元素。
e.clientX、e.clientY
事件觸發時,返回滑鼠相對瀏覽器可視區域左上角的偏移量,固定不隨頁面而改變,可視區域不包括工具欄和滾動條。兼容性:所有瀏覽器均支持。
e.pageX、e.pageY
事件觸發時,滑鼠游標到 document 文件左上角的偏移量,會隨著頁面卷軸滾動而改變,這 2 個屬性雖不是標準屬性,但得到了廣泛支持,除了 IE6/7/8。
e.offsetX、e.offsetY
事件觸發時,滑鼠游標相對父元素左上角的偏移量,左上角的基準點在不同瀏覽器各有不同,IE 以內容區左上角為基準點不包括邊框。Chrome 以邊框左上角為基準點。
e.screenX、e.screenY
事件觸發時,滑鼠游標相對於螢幕顯示器螢幕左上角的 X,Y 坐標。
$(document).on('click', function (e) { |
e.preventDefault()
阻止瀏覽器事件預設回應的函式,此函式是事件物件的一部分,可以在事件處理函式內存取。若網頁有個連結,點擊連結時通常瀏覽器會連結到該網址,如果要阻止它的預設行為。當在事件的環境中完成了某些作用,例如頁面滾動到錨點 id 的位置,通常會用到 e.preventDefault()。
$('a').click(function (e) { |
也可以寫成以下這樣:
$('#menu').click(function () { |
event.stopPropagation()
阻止事件冒泡,event.stopPropagation() 可以阻止 click 事件冒泡到父元素,透過呼叫 event.stopPropagation() 就可以避免其他所有 DOM 元素回應這個事件。點擊按鈕的事件會被按鈕處理,而且只會被按鈕處理。
$('#theLink').click(function (e) { |
鍵盤事件的事件物件屬性
鍵盤事件 | 解說 |
---|---|
keyCode | 當 keypress 事件時,返回 character code;當 keydown 或 keyup 事件時,返回 key code |
which | 當按下滑鼠按鍵,取得是哪個按鍵,值同 keyCode |
charCode | 當 keypress 事件時,返回 character code |
altKey | 布林值 (boolean),用來判斷使用者是否有按 alt 鍵 |
ctrlKey | 布林值 (boolean),用來判斷使用者是否有按 ctrl 鍵 |
shiftKey | 若事件發生時 shift 按著則為 true; |
metaKey | 布林值 (boolean),用來判斷使用者是否有按 meta 鍵 |
metaKey
若是原生的事件物件沒有 metaKey 屬性,jQuery 會將此設為與 ctrlKey 屬性相同的值。MacOS 中會是 Command 鍵設定 metaKey 屬性。which
jQuery 正規化(normalize)這個非標準事件屬性,指出在事件中按下了哪個滑鼠鍵或鍵盤按鍵。
對鍵盤事件來說,若是原生的事件沒有定義 which,但定義了 charCode 或 keyCode,which 會被設為這些屬性所定義的值。
對滑鼠事件來說,若是 which 無定義,但 button 屬性有定義,which 會依據 button 的值來設定。0 代表沒有按下任何滑鼠按鍵。
1 代表按下左鍵。
2 代表按下中鍵。
3 代表按下右鍵。(某些瀏覽器不會為右鍵點擊產生滑鼠事件)
ASCII character 對照表
Key codes 對照表
其他事件物件屬性
常用 | 解說 |
---|---|
type | 返回事件類型,例如 “click” |
timeStamp | 事件發生時的時間 timestamp (單位是 milliseconds 毫秒) |
eventPhase | 返回為一個數字,表示事件處於目前所處的傳播狀態 (event flow) |
有這些值:0: None,1: capturing phase。2: target phase,3: bubbling phase | |
data | 用於 on()函式傳遞資料給事件處理函式的 jQuery 物件。 |
- timeStamp
事件發生的時間點,格式為 Date.getTime()方法所回傳那樣,單位式毫秒。jQuery 會自行設定這個屬性,以避開 FireFox 一個存在已久的臭蟲。
事件旅行
事件旅行指的是事件傳遞的順序,分為「事件捕獲」、「事件冒泡」兩種,也就是 HTML 層級間若有事件存在,那麼點擊某一個元素,會依據這兩種其中一種方式來傳遞事件。而在 jQuery 裡面, 已經將 addEventListener 的第三參數設定為 false,也就是「事件冒泡」,所以事件傳遞會由內而外。
事件捕獲(event capturing)
事件傳遞會由外而內,addEventListener 第三參數為 true。
事件冒泡(event bubbling)
事件傳遞會由內而外,addEventListener 第三參數為 false。
事件冒泡範例
點擊「我是最裡面」,傳遞會由 a > inner > outer > document。a 設定 e.preventDefault()因此連結會無效,若再設定 e.stopPropagation() 可以阻止事件冒泡傳遞,就不會觸發其他事件。
<style> |