接上次看JS的事件冒泡和捕獲,所以順帶就把事件
相關的知識都看完好了
而且想到一個好的學習方法,第一天自己看,第二天把前一天學習的東西寫下來,一方面可以當復習,一方面當重新整理並且分享
事件對象
事件處理程序函數在處理事件時,或者說DOM
在觸發某個事件的時候,會產生一個包含事件相關信息的event
事件對象
對於不同瀏覽器環境,這個event
事件對象有一些差距
-
DOM中的事件對象
不管是
DOM0
級還是DOM2
級兼容
DOM
的瀏覽器會將一個event
對象傳入事件處理程序中常用的
event
對象的一些屬性-
type
:表示事件的類型具體用法:可以通過
type
區分,在同一個事件處理函數實現多個事件的處理,減少事件監聽,優化性能 -
currentTarget
:事件處理程序當前正在處理這個事件的元素 -
target
: 表示實際觸發事件的DOM元素,實際目標可以這么理解,
body
下面的div
被點擊,冒泡到body
,在body
上綁定了一個click
事件,這個時候觸發這個body
的點擊事件,但是這個時候的target
實際上是div
那么在事件處理程序中,還有一個
this
屬性,還有一個currentTarget
:永遠指向正在處理這個事件的元素,那么上一個例子中實際上是body
在處理這個事件,所以currentTarget
是指向body
的而 事件處理程序中的
this
指向,是一直指向currentTarget
表示正在執行和處理事件的這個元素所以,在事件沒有冒泡的情況下,這三者是可以為同一個值,但是如果是在冒泡階段事件被處理的話,則這個
target
可能不等於其他兩個值 -
preventDefault
阻止默認行為,是一個函數用法:在需要阻止默認行為的事件處理函數中,使用
event.preventDefault()
,取消默認事件,比如默認點擊a
標簽會跳轉指定鏈接等等注意: 只有
event.cancleable
屬性為true
的事件類型,才可以使用preventDefault
-
stopPropagation
阻止事件冒泡和捕獲,也是一個函數- 這個用的比較常見,阻止事件冒泡和捕獲,只要這個事件被處理,不會順着事件流往捕獲方向或者冒泡方向傳遞
-
eventPhase
獲取事件當前正處於事件流的哪個階段- 事件流三個階段: 捕獲階段,冒泡階段,處於目標階段
- 事件處理程序中的
event.eventPhase
分別對應值:1,3,2
-
上述
event
屬性和方法,盡在事件處理程序執行期間存在,事件處理程序一旦執行完畢,會立即銷毀
-
-
IE中的事件對象
IE中的
event
對象跟DOM
中的事件對象有一定的差別,最重要的就是IE
中的事件對象,如果是使用DOM0
級的方法添加事件處理程序是,event
對象會掛載到window
下面?window?window?是的沒錯,獲取事件對象的時候,是通過window.event
來拿到事件對象,如果使用html
指定事件處理程序或者是DOM2
級都都不會有這個問題,和DOM
級別類似,會有一個event
對象傳入到事件處理程序但是
IE
中的事件對象,對應的屬性名和方法名跟DOM
中事件對象的名字有很大不一樣cancelBubble == stopPropagation
阻止事件冒泡,但是不是個方法是一個屬性returnValue == preventDefault
阻止默認事件,但是不是個方法,是一個屬性srcElement == target
實際觸發目標type == type
用來區分事件類型,這個沒有區別
要記住的還是,如果在
IE
環境下,使用DOM0
級指定事件處理程序的話,獲取event
對象需要從window.event
這樣獲取例如:
var btn= document.getElementById('test') // DOM0級指定 btn.onclick=function(){ alert(window.event.target.srcElement === this) //true } // DOM2級 btn.addEventListener('click',function(event){ alert(event.srcElment === this) //true })
還有就是
IE
環境下阻止事件冒泡和默認處理程序都是屬性,不是方法,只需要把對應的屬性設置為false
例如:
var link = document..getElementById('test') link.onclick = function(){ window.event.returnValue = false; //阻止默認事件 }
IE
中的cancleBuble只是取消冒泡,因為IE環境不支持事件捕獲,哈哈哈哈然后就是完善一下之前的
EventUtil
,實現跨瀏覽器的獲取事件對象,還有阻止冒泡和默認事件處理程序,代碼如下getTarget(event){ return event || window.event //IE環境下可能是WINDOW.event }, preventDefault(event){ if(event.preventDefault){ event.preventDefault() }else{ event.returnValue = false // IE環境下沒有preventDefault,是通過設置returnValue取消默認 } }, stopPropagation(event){ if(event.stopPropagation){ event.stopPropagation() }else{ event.cancelBuble = false } }
事件類型
DOM3級完善了事件類型,用來區分事件類型的不同信息,類似:鼠標事件,焦點事件,鍵盤事件,文本時間,滾輪事件等等
-
UI事件
指的是那些不一定與用戶操作有管的事件,包括一些DOM和元素的交互時間,例如
load
事件unload
事件-
load
事件- 最常用的事件,
- 觸發對象:
window
, - 觸發時間:頁面完全加載后(包括所有圖像,JS文件,CSS等外部資源)
- 如何捕獲:
DOM2
級寫法:監聽window
對象,例如window.addEventListener('load',function(){})
HTML
級寫法,由於HTML
寫法無法拿到window
對象,所以會直接寫在body
上面,一般來說,在window
上發生的任何事件都可以在body
元素上通過對應的特性來指定,所有的瀏覽器都能很好地支持這種方式,但是任然推薦使用DOM0
或DOM2
等javascript
的方法來綁定window
對象的時間按處理程序img,script,link,video
等標簽也有load
事件
-
unload
事件- 一般用來:在這個事件清除引用,清理內存
- 觸發對象:
window
- 觸發時間:文檔被完全卸載之后觸發,此時可能一些對象和變量已經被卸載,注意引用關系
-
resize
事件- 區別:在
DOM
瀏覽器和IE
環境有區別,event.target
屬性的實際觸發對象不一樣,在DOM
瀏覽器中,這個屬性指向document
,但是在IE
環境中,這個值沒有指定 - 兼容性:在
firefox
瀏覽器,resize
的過程不會持續觸發這個事件,只在開始和結束,兩個觸發,而在其他瀏覽器,在拖拽的過程中是會一直觸發這個事件 - 觸發對象:
window
- 觸發事件:窗口大小發生
1px
的改變時候,最大最小化窗口的時候 - 如何捕獲:參考
load
事件,可以用window
對象捕獲,也可以用body
標簽捕獲
- 區別:在
-
scroll
事件- 觸發對象:
window
- 捕獲方式: 和
load
方法類似 - 注意:根據
document.compatMode
渲染模式,有不同的表現,在compatMode==='CSS1Copat'
標准模式時,除了Safari
瀏覽器,所有的都會通過html
這個元素反應這個變化,而在混雜模式時,是通過body
元素的scrollLeft
和scrollTop
來獲取這個具體的bian'hua數值,而現在基本上混雜模式和標准模式已經混合了,區分沒有這么詳細
- 觸發對象:
-
-
焦點事件
在頁面元素失去或者獲得焦點的時候觸發,可以用來知曉用戶在頁面上的行蹤
主要用的比較多的是
focus
,blur
,這兩個事件表示,元素獲得焦點和失去焦點,不會冒泡focusin,focusout
用來表示焦點進入和焦點失去事件,**這兩個事件會冒泡雖然上述常用事件有的不會冒泡什么,但是,仍然會走捕獲階段,所以仍然可以通過捕獲階段進行一些外級操作,當然是瀏覽器支持捕獲階段
觸發元素:所有元素都可觸發
捕獲方式:
DOM0
級,DOM2
級,或者HTML
方法均可捕獲,IE
瀏覽器環境方式也可以 -
鼠標與滾輪事件
鼠標和滾輪事件也是在
DOM3
級事件中定義的,主要有,單擊,點擊,雙擊,鼠標移入,鼠標移出,等除了鼠標移入
mouseenter
和鼠標移除mouseleave
所有的鼠標事件都會冒泡,也是可以取消的,而取消鼠標事件將會影響瀏覽器的默認行為,取消鼠標事件的默認行為還會影響其他事件,因為鼠標事件可能和其他事件是有聯系的一個
click
事件,前面包括了一個鼠標按下mousedown
和鼠標放開兩個事件mouseup
,也就是觸發click
事件前會先觸發前兩個事件同理,雙擊事件
doubleclick
事件包括兩個click
事件,前面又有兩個mouseup
和mousedown
事件主要用處
- 客戶區坐標位置
event.clientX
和event.clientY
- 鼠標事件,相對於瀏覽器視口的位置
- 頁面坐標位置
event.pageX
和event.pageY
- 鼠標事件,相對於頁面的位置
- IE8及更早版本不支持這兩個屬性,但是也可以通過鼠標相對於視口位置+頁面滾動屬性算出=鼠標相對於頁面的位置
- 屏幕坐標位置
event.screenX
和event.screenY
- 鼠標事件,相對於整個屏幕的位置
- 修改鍵/點擊鼠標時同時按下了多功能鍵(
ctrl
,alt
等)- 對應的鍵,直接在點擊事件的對應屬性上面
- 例如:
shift
鍵 就在event.shiftKey
這個屬性上
- 相關元素
- 鼠標移入移出的來源元素和目標元素
- 獲取方式:
event.relatedTarget
- 分別在
mouseout
和mouseenter
時表示 目標獲取光標元素和目標失去光標元素 - 在
IE8
之前的沒有這個屬性,但是分別有兩個fromElment
和toElement
用來獲取這兩個相關元素
- 鼠標按鈕
- 鼠標事件(例如點擊事件時,點擊的是哪個按鈕,左鍵,中鍵,右鍵等)
- 屬性名:
button
- 屬性含義:
0 : 左鍵按下,1:中鍵按下,2:右鍵按下
IE8
及更早版本瀏覽器也有這個屬性,但是對應值有比較大的區別,區分的更為細致
- 更多事件信息
- 屬性名:
detail
- 表示鼠標點擊次數
- 屬性名:
- 鼠標滾輪事件
- 我真是沒想到支持的這么詳細,hhh
- 觸摸設備
- 這個還和后面的觸摸事件有一定的區別
- 這個表示鼠標事件在一些移動設備中的區別表現
- 例如:
- 在移動設備中不支持
dblclick
事件,雙擊會放大畫面,而且不能改變該行為 - 輕擊可點擊單元會觸發
mousemove
事件,如果此事件會導致內容變化,將不再發生其他事件,如果不會觸發任何事件,那么依次會發生mousedown,mouseup,click
事件,可點擊單元表示一些會產生默認操作的元素:比如a
標簽
- 無障礙性問題
- 鼠標設備事件需要針對無障礙性考慮更多易用性和點擊操作邏輯
- 客戶區坐標位置
-
鍵盤與文本事件
主要是一些鍵盤輸入和文本鍵入的事件,是說
DOM2
級事件最初規定了鍵盤事件,但是后來刪掉了,所以目前主要支持的還是DOM0級
事件和DOM3
級事件,但是DOM3
級事件暫時沒有特別完善主要事件
keydown
,keypress
,keyup
,理論上所有的元素都支持這三個事件,但是實際上只有文本輸入框支持最多觸發順序
keydown,keypress,keyup
,並且keydown
和keypress
都是在文本框發生變化之前觸發,而keyup
事件則是在文本框已經變化之后觸發,如果用戶一直按住一個字符不放,則會一直觸發keydown
和keypress
事件還有一個新增的文本事件
textInput
,實際上是對keypress
的補充,用意是將文本顯示給用戶之前更加容易攔截文本,在文本插入文本框之前會觸發textInput
事件常用鍵盤事件屬性
- 鍵碼
keyCode
- 觸發時間:
keydown
和keyup
時,event對象會有一個keyCode
屬性 - 表示:按下按鍵的對應的小寫字母或數字對應的ASCII碼相同
- 觸發時間:
- 字符編碼
charCode
- 觸發時間:
keypress
事件觸發時 - 使用方式: 首先檢查
charCode
是否可用,如果有的話則表示的是 按下鍵對應字符的ASCII碼,而IE8
及更早版本,則是在keyCode
表示字符對應的ASCII碼 - 所以:字符對應的ASCII碼不一定在
charCode
,在IE8
及老舊瀏覽器也可能在keyCode
- 用法:如果
charCode
可用的話,可以通過字符串類方法String.fromCharCode
轉化為實際的字符
- 觸發時間:
- DOM3級新增了
char
和key
- 同時整合了
charCode
和keyCode
key
:表示對應的文本字符,包括大小寫,就是實際的鍵入字符char
:表現形式在按下字符時表現和key
一致,但是對於非字符時,char
為null
- 新增了
location
屬性,表示按下了鍵盤什么位置的同一個按鍵,例如鍵盤左邊的shift
和右邊的shift
- 同時整合了
- textInput事件
- 新增的文本輸入事件,只在可編輯區域觸發,主要用域監聽文本的變化,新增data屬性,表示修改實際文本
- 新增屬性:
inputMethod
,用來區分輸入方式,是復制進來的,還是拖放進來的,還是手寫輸入,語音輸入等
DOM3級的鍵盤輸入事件很美好,但是不知道實際支持情況,而且還要做兼容,之前遇到一個
number
類型的input
輸入框,就累個夠嗆,候選字等,輸入法越做越優秀,事件越來越復雜- 設備中的其他按鍵事件
- 例如一些手柄的事件,加號,減號等,暫時沒用到
- 鍵碼
-
復合事件
是
DOM3
級新增的一類事件,用域處理IME
的輸入序列,暫時沒接觸,也是一類多功能輸入事件吧 -
變動事件
是
DOM2
級的變動事件表示:DOM中某一部分發生變化時給出提示,變動事件是為
XML
或者HTML DOM
設計的,並不特定於某種語言。主要有:
- 節點移除
- 節點插入
- 刪除節點等
-
HTML5事件
-
contextmenu
上下文菜單事件- 意義:通過鼠標右鍵,調出上下文菜單,鼠標右鍵顯示事件
- 觸發元素:所有元素,
- 是否冒泡:會冒泡
- 注意:首先需要阻止默認事件處理程序,然后重新寫事件處理程序,有可能影響瀏覽器默認行文
-
beforeunload
事件- 意義:頁面卸載之前用來挽留頁面
- 觸發元素:
window
對象
-
DOMContentLoaded
事件- 意義:
DOM
樹完整形成之后觸發 - 觸發元素:
window
對象
- 意義:
-
readystatechange
事件- 意義:元素加載狀態發生變化時
- 觸發元素:部分媒體元素,
script
標簽等 - 每個對象都有一個
readystate
的狀態屬性,會有以下狀態(但不是所有狀態都會正常變化)uninitialized
未初始化狀態loading
正在加載loaded
加載完畢interactive
可以操作對象complete
完成
- 但是不是所有對象都有這些完整的階段,可能會跳過
-
pagehide
和pageshow
事件- 意義:從內存中取出/進入視野時觸發,不會觸發
load
事件,不會重新加載頁面,只是從頁面回顯 - 一般發生在:前進/后退按鈕點擊的時候
- 相關屬性
event.persisted
是否被緩存在bfcache
中 - 觸發元素:
window
。。。太多了,還有好多事件類型,回頭再填坑了,記錄不下去了
- 意義:從內存中取出/進入視野時觸發,不會觸發
-