事件
http://www.w3school.com.cn/jsref/dom_obj_event.asp
JavaScript與HTML之間的交互式通過事件實現的。可以用偵聽器(處理程序)來預定事件,在傳統軟件工程中被稱為觀察者模式的模型,支持頁面的行為和頁面的外觀之間的松散耦合。
IE事件流是事件冒泡流,而Netscape事件流是事件捕獲流。(放心使用事件冒泡)
DOM2級事件 規定的事件流包括三個階段:事件捕獲階段、處于目標階段和事件冒泡階段。
事件處理程序
函數體內有局部變量event,可以直接訪問事件對象。不需要定義
<input type="button" value="Click Me" onclick="alert(event.type)" >
在函數內部,this值等于事件的目標元素.
<input type="button" value="Click Me" onclick="alert(this.value)" >
在HTML中指定事件處理程序有兩個缺點
- 時差問題,HTML元素一出現就觸發相應的事件,而當時的事件處理程序有可能未具備執行條件。
- 擴展事件處理程序的作用域鏈在不同瀏覽器會導致不同的結果。可能會在訪問非限定對象時出錯。
- 導致HTML與JavaScript代碼緊密耦合。(更換事件處理程序要改動兩個地方)
DOM0級事件處理程序:
element.event = function(){}
DOM2級事件處理程序:
-
addEventListener(event_name,handler,false)
IE:attachEvent(event_name,handler)
-
removeEventListener(event_name,handler,false)
//傳入的handler決定了刪除哪一個handler綁定的事件
IE:detachEvent(event_name,handler)
在IE使用attachEvent()作用于在全局作用域。this = window
; 執行時按添加的相反順序執行。
屬性/方法 | 類型 | 讀/寫 | 說明 |
---|---|---|---|
bubbles | Boolean | 只讀 | 表明事件是否冒泡 |
stopPropagation() | Function | 只讀 | 取消事件的進一步捕獲或冒泡。如果bubbles為true,則可以使用這個方法 |
stopImmediatePropagation() | Function | 只讀 | 取消事件的進一步捕獲或冒泡,同時阻止任何事件處理程序被調用(DOM3級事件中新增) |
cancelable | Boolean | 只讀 | 表明是否可以取消事件的默認行為 |
preventDefault() | Function | 只讀 | 取消事件的默認行為。如果cancelable是true,則可以使用這個方法 |
defaultPrevented | Boolean | 只讀 | 為true表示已經調用了preventDefault()(DOM3級事件中新增) |
currentTarget | Element | 只讀 | 其事件處理程序當前正在處理事件的那個元素(currentTarget始終===this,即處理事件的元素) |
target | Element | 只讀 | 直接事件目標,真正觸發事件的目標 |
detail | Integer | 只讀 | 與事件相關的細節信息 |
eventPhase | Integer | 只讀 | 調用事件處理程序的階段:1表示捕獲階段,2表示處于目標階段,3表示冒泡階段 |
trusted | Boolean | 只讀 | 為true表示事件是由瀏覽器生成的。為false表示事件是由開發人員通過JavaScript創建的(DOM3級事件中新增) |
type | String | 只讀 | 被觸發的事件的類型 |
view | AbstractView | 只讀 | 與事件關聯的抽象視圖。等同于發生事件的window對象 |
在事件處理程序內部,對象this
始終等于 currentTarget
的值。target
只包含事件的實際目標。看下面例子
document.body.onclick = function(event){
alert(event.currentTarget === document.body); //true
alert(this === document.body); //true
alert(event.tagget === document.getElementById("myBtn"); //true
}
點擊按鈕時 this
和 currentTarget
等于 document.body
,但 target
卻等于按鈕元素(事件的真正目標).
- 在需要通過一個函數處理多個事件時可以使用type屬性.(
event.type
返回事件對象類型) - 阻止特定事件的默認行為,可以使用
preventDefault()
方法.(當cancelable == true
) -
stopPropagation()
方法用于立即停止事件在DOM層次的傳播(取消冒泡或者捕獲)
IE中的事件對象
- 使用DOM0級方法添加事件處理程序時,
event
對象作為window
對象的一個屬性存在。
var btn = document.getElement("myBtn");
btn.onclick = function(){
var event = window.event;
alert(event.type); //click
}
btn.attachEvent("onclick", function(event){
alert(event.type);
});
屬相和方法 | 類型 | 讀寫 | 說明 |
---|---|---|---|
cancelBubble | Boolean | 讀/寫 | 默認值為fasle,設置為true,就可以取消事件冒泡 與 DOM 中的 stopPropagation()方法的作用相同 |
returnValue | Boolean | 讀/寫 | 默認為 true, 設置為fasle。 就可以取消事件的默認行為 |
srcElement | Element | 只讀 | 事件的目標(與DOM中的target屬性相同) |
type | String | 只讀 | 被觸發事件的類型 |
- 事件處理程序的作用域是根據指定它的方式確定的,所以不能認為
this
會始終等于事件目標。故而,最好還是使用event.srcElement
比較保險. -
returnValue
屬性相當于DOM中的preventDefault()
方法.它們的作用都是取消給定事件的默認行為。只要將該屬性設置為false就能組織默認行為。 -
cancelBubble
屬性與DOM中的stopPropagation()方法作用相同,用來停止事件冒泡的。IE只能取消事件冒泡。通過將cancelBubble設置為true,就可阻止事件通過冒泡而觸發的處理程序。
s
事件類型
DOM3級事件規定了以下幾類事件:
- UI
- 焦點
- 鼠標
- 滾輪
- 文本
- 鍵盤
- 合成(IME 輸入法)
- 變動(底層DOM結構發生變化觸發)
- 變動名稱事件
UI事件
load
: 當頁面完全加載后在window上面觸發,當所有框架都加載完畢時在框架集上面觸發,當圖像加載完畢時在<img>元素上面觸發。或者當嵌入的內容加載完畢時在元素上面觸發。unload
:當頁面完全卸載后在window上面觸發,當所有框架都卸載后在框架集上面觸發,或者當嵌入的內容卸載完畢后在元素上面觸發。abort
:當用戶停止下載過程嵌入內容沒有加載完觸發。error
: 當發生JavasScript錯誤時在window上面觸發,當無法加載圖片時在<img>元素上面觸發,當元素加載嵌入內容時在元素上面觸發,或者當有一或多個框架無法加載時在框架集上面觸發。select
: 當用戶選擇文本框( or )中的一個可多個字符時觸發。resize
: 當窗口或框架的大小變化時在window或框架上面觸發;scroll
:當用戶流動帶有流動條的元素中的內容時,在該元素上面觸發。元素中包含所加載頁面的流動條。
焦點事件
blur
:失去焦點時觸發,這個事件不會冒泡focus
:獲得焦點時觸發,不冒泡focusin
:在獲得焦點時觸發,但他冒泡,DOM3新增focusout
:在失去焦點時觸發,冒泡
鼠標及滾輪事件
click
:在單擊主鼠標按鈕(一般是左鍵)或者按下回車時觸發;這意味著onclick事件處理程序既可以通過鼠標也可以通過鍵盤執行。dbclick
:雙擊主鼠標按鈕(一般是左鍵)或者按下回車鍵時觸發。mousedown
:按下任意鼠標按鈕時觸發;不能通過鍵盤觸發。mouseup
:釋放鼠標按鈕時觸發;不能通過鍵盤觸發。mouseenter
:在鼠標光標從元素外部首次移動到元素范圍之內時觸發;這個事件不冒泡,而且光標移動到元素的后代元素上不會觸發;IE、Firefox9+和Opera支持這個事件。mouseleave
:在鼠標光標從元素上方移動到元素范圍之外時觸發;這個事件不冒泡,而且光標移動到元素的后代元素上不會觸發;IE、Firefox9+和Opera支持這個事件。mousemove
:在鼠標光標在元素內部移動時重復地觸發;不能通過鍵盤觸發。mouseout
:在鼠標位于一個元素上方,然后移動到另一個元素時觸發,另一個元素可以是這個元素的子元素;不能通過鍵盤觸發。mouseover
:在鼠標位于一個元素外部,然后將其首次移動到另一個元素邊界之內時觸發;不能通過鍵盤觸發。
- (客戶區坐標)鼠標事件位置信息保存在事件對象中的
clientX
和clientY
屬性中.- (頁面坐標位置)事件對象
pageX
和pageY
屬性表示鼠標光標在頁面中的位置,坐標運算從頁面本身而非是視口的左邊和頂邊計算的。screenX
和screenY
屬性確定鼠標事件發生時鼠標指針相對于整個屏幕的坐標信息。(相對于電腦屏幕的位置)- 修改鍵狀態屬性(判斷是否按下):
shiftKey
、ctrlKey
、altKey
、metaKey
(在windows是windows鍵,在蘋果機是cmd
鍵);- 對于
mousedown
和mouseup
事件來說,在其event對象存在一個button
屬性。(0:主鼠標按鈕,1:中間鼠標按鈕,2:次鼠標按鈕)- 鼠標滾輪事件:
mousewheel
,返回值中的wheelDelta
正負代表滾輪的方向。(Opera 9.5以前的版本正負號是顛倒的)
鍵盤與文本事件
keydown
keypress
keyup
- 只有一個文本事件:
textInput
,可以用于攔截文本。(在文本輸入文本框之前會觸發該事件)。- event 對象上還有一個屬性:inputMethod,返回值是文本輸入到文本框中的方式。
復合事件(用于處理IME輸入序列)
compositionstart
:要開始輸入compositionupdate
:插入新字符compositionend
:復合系統關閉,返回正常鍵盤輸入狀態
event.data
屬性:
compositionstart
時訪問data
:正在編輯的文本;compositionupdate
時訪問data
:正插入的新字符;compositionend
時訪問data
:插入的所有字符;
變動事件(貌似作廢了很多變動事件,跨瀏覽器不好,不建議用)
DOMNodeInserted
:在一個節點作為子節點被插入到另一個節點中時;DOMNodeRemoved
:在節點從其父節點中被移除時;
其中(event.target)是被刪除的節點,由于觸發時節點尚未從其父節點刪除,因此其parentNode屬性仍然指向父節點.(和event.relatedNode相同,包含對目標節點父節點的引用).DOMNodeInsertedIntoDocument
:在一個節點被直接插入文檔,或通過子樹間接插入文檔之后觸發。這個事件在DOMNodeInserted
之后觸發;DOMNodeRemovedFromDocument
:在一個節點被直接從文檔中移除,或通過子樹間接從文檔中移除之前觸發。這個事件在DOMNodeRemoved
之后觸發;DOMSubtreeModified
:在DOM
結構中發生任何變化時觸發;DOMAttrModified
:在特性被修改之后觸發;DOMCharacterDataModified
:在文本節點的值發生變化時觸發;
HTML5事件
contentmenu
: 右鍵調出上下文菜單事件,在兼容DOM的瀏覽器中,可以使用event.preventDafault()阻止元素發生的默認行為。IE將event.returnValue值設為false;beforeunload
: 頁面卸載前的事件。這個事件會在瀏覽器卸載頁面之前觸發。EventUtil.addHandler(window, "beforeunload", function(event){ event = EventUtil.getEvent(event); var message = "I'm GGG"; event.returnValue = message; return message; }
DOMContentLoaded
事件 (IE:readystatechange
事件)
window
的load
事件會在頁面的一切都加載完畢時觸發。而DOMContentLoaded
事件則在形成完整的DOM樹之后就會觸發,不會理會圖像、JavaScript文件、CSS文件或其他資源是否已經下載完畢。pageshow
和pagehide
事件
Firefox 和 Opera有個特性:往返緩存,如果頁面位于bfcache中,那么再次打開該頁面就不會觸發load
事件.hashchange
事件
在URL的參數列表(以及URL中#號后面的所有字符串)發生變化時通知。
此時event對象包含兩個額外屬性:oldURL
和newURL
設備事件
orientationchange
事件(Safari)
當設備改變縱向或橫向時觸發事件。
事件的值可以通過window.orientation 的返回值判斷。 (0:肖像模式,-90表示向右旋轉的橫向模式,90表示向左旋轉的橫向模式,180表示頭朝下)MozOrientation
事件
Firefox 為檢測設備的方向引入了一個名為MozOrientation
的新事件(非標準)該事件只能提供一個平面的方向變化。
事件內event對象包含三個屬性:x、y、z,值都介于1到-1之間,表示不同設備坐標軸上的方向。
x為向左傾斜的值,向右會減少。y為向接近用戶的方向傾斜的值,z檢測垂直加速度,1表示靜止不動,0為失重。deviceorientation
事件
和MozOrientation 類似.但意圖是告訴開發人員設備在空間中朝向哪兒。
事件對象包含以下五個屬性:
alpha
: 在圍繞z軸旋轉(左右),y軸的度數差;是一個介于0到360之間的浮點數。beta
: 在圍繞x軸旋轉(前后),z軸的度數差;是一個介于-180到180之間的浮點數。gamma
: 在圍繞y軸旋轉(扭轉),z軸的度數差;是一個介于-90到90之間的浮點數。absolute
: 布爾值,表示設備是否返回一個絕對值。compassCalibrated
: 布爾值,表示設備的指南針是否校準過。方向圖.jpg
devicemotion
事件
這個事件告訴開發人員設備什么時候移動,檢測設備是不是往下掉或者被走著的人拿在手里
acceleration
: 一個包含x,y,z屬性的對象,不考慮重力的情況下告訴你在每個方向上的加速度。accelerationIncludingGravity
: 一個包含x,y,z屬性的對象,在考慮z軸自然重力加速度的情況下告訴你每個方向上的加速度。interval
: 以毫秒表示的時間值,必須在另一個devicemotion事件觸發前傳入。rotationRate
: 一個包含表示方向的alpha、beta和gamma屬性的對象
如果讀取不了他們值就會返回null,所以使用屬性先檢測他們的值不是null.
觸摸和手勢事件
觸碰事件
touchstart
: 當手指觸摸屏幕時出發。即使已經有一個手指放在了屏幕上也會觸發。touchmove
: 當手指在屏幕上滑動時連續觸發。在事件期間可以調用preventDefault()來阻止滾動。touchend
: 當手指從屏幕上移開時觸發。touchcancel
: 當系統停止跟蹤觸摸時觸發。
觸摸事件不僅提供了鼠標事件常見的屬性,還包含下列三個用于跟蹤觸摸的屬性
touches
: 表示當前跟蹤觸摸操作的Touch對象數組.targetTouchs
: 特定于事件目標的Touch對象數組.changeTouches
: 表示自上次觸摸以來發生了什么改變的Touch對象數組。
每個Touch對象包括下列屬性:
clientX
、clientY
、identifier
(標識觸摸的唯一ID)、pageX
、pageY
、screenX
、screenY
、target
(觸摸的DOM節點目標)
手勢事件
當兩個手指觸碰屏幕時就會產生手勢。
gesturestart
: 當一個手指已經俺在屏幕上而另一個手指又觸碰屏幕時觸發。gesturechange
: 當觸摸屏幕的任何一個手指的位置發生變化時觸發。gestureend
: 當任何一個手指從屏幕上面移開時觸發。
每個手勢事件對象包含標準鼠標事件屬性外,還另外包含兩個額外的屬性:rotation
和scale
,rotation
表示手指變化引起的旋轉角度,scale
屬性表示兩個手指間距離的變化情況。
內存和性能
在JavaScript中,添加到頁面上的事件處理程序數量將直接關系到頁面的整體運行性能。
對“事件處理程序過多”問題的解決方案就是事件委托(在同一個委托函數中對id進行分類并分別處理)。
使用事件委托好處是:
-
document
對象很快就可以訪問,而且可以在頁面生命周期的任何時點上為它添加事件處理程序(無需等待DOMContentLoaded
或load
事件)。換句話說,只要可點擊的元素呈現在頁面上,就可以立即具備適當的功能。 - 在頁面中設置事件處理程序所需的時間更少。只添加一個事件處理程序所需的
DOM
引用更少,所花的時間也更少。 - 整個頁面占用的內存空間更少,能夠提升整體性能。
使用removeChild()
、replaceChild()
或innerHTML()
時,要先將元素事件處理程序移除掉,避免無法回收。
另一種情況就是卸載頁面的時候。IE8或更早版本在這種情況下是問題最多的瀏覽器。如果在頁面被卸載時沒有清理干凈事件處理程序有可能會滯留在內存中。
模擬事件
可以在
document
對象上使用createEvent()
方法創建event對象.接受一個參數,即表示要創建的事件類型的字符串。這個字符串可以是下列幾個字符串之一。(DOM2為英文復數形式,DOM3為單數)
UIEvents
: 一般化的UI事件,鼠標事件和鍵盤事件都繼承自UI事件。MouseEvents
: 一般化的鼠標事件。MutationEvents
: 一般化的DOM變動事件。HTMLEvents
: 一般化的HTML事件。
表單腳本
在HTML中,表單是由<form>元素來表示的。而在JavaScript中,表單對應的則是HTMLFormElement類型。
HTMLFormElement有它自己下列獨有的屬性和方法:
-
acceptCharset
: 服務器能夠處理的字符集,等價于HTML中的accept-charset特性。 -
action
: 接受請求的URL;等價于HTML中的action特性。 -
elements
: 表單中所有控件的集合(HTMLCollection)。 -
enctype
: 請求的編碼類型;等價于HTML中的enctype特性。 -
length
: 表單中控件數量 -
name
: 表單的名稱,等價于HTML的name特性。 -
reset()
: 將所有表單域重置為默認值。 -
submit()
: 提交表單。 -
target
: 用于發送請求和接受響應的窗口名稱;等價于HTML的target特性。
注意事項:
- 提交表單,只要將其
type
特性的值設置為submit
即可。 - 用這種方式提交表單時,瀏覽器會將請求發送給服務器之前觸發submit事件,這樣的話我們就有機會去驗證表單事件,阻止這個事件的默認行為就可以取消表單提交。(
preventDefault()
) - 在表單中使用
form.submit()
也可以提交表單,但不會觸發submit事件。 - 調用
reset()
方法和type
設置為reset
可以用來重置表單.
所有表單字段都擁有相同一組屬性:
-
disabled
、form
、name
、readOnly
、tabIndex
、type
、value
文本框腳本
- <textarea>元素呈現多行文本框,指定文本框的大小可以使用rows和cols特性.
- 在文本框中選擇字符會觸發select()事件,其中的兩個屬性
selectionStart
和selectionEnd
表示所選擇字符文本的范圍。(IE使用document.selection對象). - 選擇部分文本的方法
text.setSelectionRange(firstCharIndex,lastCharIndex)
(IE使用createTextRange()
、moveStart()
、moveEnd()
) - 過濾輸入在keypress中獲取字符編碼并用preventDefault()進行過濾.(注意不要屏蔽一些功能鍵,不要屏蔽字符編碼小于10和ctrl鍵
event.ctrlKey
) - 剪貼板
6個剪貼板事件
-
beforecopy
、copy
、beforecut
、cut
、beforepaste
、paste
訪問剪貼板數據可以使用clipboardData
-
HTML5約束驗證API
JS被禁用時可以通過這些讓瀏覽器根據標記規則執行驗證,然后自己顯示適當的錯誤信息。
-
required
必填字段 -
pattern
正則表達式屬性 - JS代碼中可以通過使用
checkValidity()
方法檢測表單某個字段是否有效(根據上面列舉的約束。) -
validity
屬性會告訴你哪些字段有效或者無效。這個對象包含一系列屬性,每個屬性都會返回一個布爾值。 -
novalidate
屬性禁用驗證
選擇框腳本
HTMLSelectElement
-
add(newOption,relOption)
: 向控件插入新的<option> 元素,其位置在相關項之前. -
multiple
: 布爾值,表示是否允許多項選擇;等價于HTML的multiple特性。 -
options
: 控件中所有<option>元素的HTMLCollection。 -
remove(index)
: 移除給定位置的選項。 -
selectedIndex
: 基于0的選中項的索引,如果沒有選中項,則值為-1。對于支持多選的控件,只保存選中項中第一項的索引。 -
size
: 選擇框中可見的行數;等價于HTML中的size特性。
HTMLOptionElement
-
index
: 當前選項在options集合中的索引 -
label
: 當前選項的標簽;等價于HTML中的label特性 -
selected
: 布爾值,表示當前選項是否被選中。將這個屬性設置為true可以選中當前選項。 -
text
: 選項的文本。 -
value
: 選項的值(等價于HTML中的value特性)