DOM事件類型詳解


一、表單事件:
input事件當<input>、<textarea>的值發生變化時觸發。此外,打開contenteditable屬性的元素,只要值發生變化,也會觸發input事件。input事件的一個特點,就是會連續觸發,比如用戶每次按下一次按鍵,就會觸發一次input事件。
select事件當在<input>、<textarea>中選中文本時觸發。
Change事件當<input>、<select>、<textarea>的值發生變化時觸發。它與input事件的最大不同,就是不會連續觸發,只有當全部修改完成時才會觸發,而且input事件必然會引發change事件。具體來說,分成以下幾種情況。
激活單選框(radio)或復選框(checkbox)時觸發。
用戶提交時觸發。比如,從下列列表(select)完成選擇,在日期或文件輸入框完成選擇。
當文本框或textarea元素的值發生改變,並且喪失焦點時觸發。
reset事件當表單重置(所有表單成員變回默認值)時由form元素觸發。
submit事件當表單數據向服務器提交時由form元素觸發。
二、文檔事件
以下事件與網頁的加載與卸載相關
beforeunload事件當窗口將要關閉,或者document和網頁資源將要卸載時觸發。它可以用來防止用戶不當心關閉網頁。該事件的默認動作就是關閉當前窗口或文檔。如果在監聽函數中,調用了event.preventDefault(),或者對事件對象的returnValue屬性賦予一個非空的值,就會自動跳出一個確認框,讓用戶確認是否關閉網頁。如果用戶點擊“取消”按鈕,網頁就不會關閉。監聽函數所返回的字符串,會顯示在確認對話框之中
window.addEventListener('beforeunload', function( event ) {
  event.returnValue = '你確認要離開嗎?';//或event.preventDefault();
});
unload事件在窗口關閉或者document對象將要卸載時觸發,發生在window、body、frameset等對象上面。它的觸發順序排在beforeunload、pagehide事件后面。unload事件只在頁面沒有被瀏覽器緩存時才會觸發,換言之,如果通過按下“前進/后退”導致頁面卸載,並不會觸發unload事件。當unload事件發生時,document對象處於一個特殊狀態。所有資源依然存在,但是對用戶來說都不可見,UI互動(window.open、alert、confirm方法等)全部無效。這時即使拋出錯誤,也不能停止文檔的卸載。
load事件在頁面加載成功時觸發,error事件在頁面加載失敗時觸發。注意,頁面從瀏覽器緩存加載,並不會觸發load事件。這兩個事件實際上屬於進度事件,不僅發生在document對象,還發生在各種外部資源上面。瀏覽網頁就是一個加載各種資源的過程,圖像(image)、樣式表(style sheet)、腳本(script)、視頻(video)、音頻(audio)、Ajax請求(XMLHttpRequest)等等。這些資源和document對象、window對象、XMLHttpRequestUpload對象,都會觸發load事件和error事件。
pageshow事件,pagehide事件:默認情況下,瀏覽器會在當前會話(session)緩存頁面,當用戶點擊“前進/后退”按鈕時,瀏覽器就會從緩存中加載頁面。
pageshow事件在頁面加載時觸發,包括第一次加載和從緩存加載兩種情況。如果要指定頁面每次加載(不管是不是從瀏覽器緩存)時都運行的代碼,可以放在這個事件的監聽函數。第一次加載時,它的觸發順序排在load事件后面。從緩存加載時,load事件不會觸發,因為網頁在緩存中的樣子通常是load事件的監聽函數運行后的樣子,所以不必重復執行。同理,如果是從緩存中加載頁面,網頁內初始化的JavaScript腳本(比如DOMContentLoaded事件的監聽函數)也不會執行。pageshow事件有一個persisted屬性,返回一個布爾值。頁面第一次加載時,這個屬性是false;當頁面從緩存加載時,這個屬性是true。if (event.persisted){...}
pagehide事件與pageshow事件類似,當用戶通過“前進/后退”按鈕,離開當前頁面時觸發。它與unload事件的區別在於,如果在window對象上定義unload事件的監聽函數之后,頁面不會保存在緩存中,而使用pagehide事件,頁面會保存在緩存中。pagehide事件的event對象有一個persisted屬性,將這個屬性設為true,就表示頁面要保存在緩存中;設為false,表示網頁不保存在緩存中,這時如果設置了unload事件的監聽函數,該函數將在pagehide事件后立即運行。如果頁面包含frame或iframe元素,則frame頁面的pageshow事件和pagehide事件,都會在主頁面之前觸發。
以下事件與文檔狀態相關:
DOMContentLoaded事件當HTML文檔下載並解析完成以后,就會在document對象上觸發DOMContentLoaded事件。這時,僅僅完成了HTML文檔的解析(整張頁面的DOM生成),所有外部資源(樣式表、腳本、iframe等等)可能還沒有下載結束。也就是說,這個事件比load事件,發生時間早得多。注意, 網頁的JavaScript腳本是同步執行的,所以定義DOMContentLoaded事件的監聽函數,應該放在所有腳本的最前面。否則腳本一旦發生堵塞,將推遲觸發DOMContentLoaded事件。IE8不支持DOMContentLoaded,可以使用readystatechange事件,在低版本的IE中代替DOMContentLoaded事件。
readystatechange事件發生在Document對象和XMLHttpRequest對象,當它們的readyState屬性發生變化時觸發。
以下事件與窗口行為有關:
scroll事件在文檔或文檔元素滾動時觸發,主要出現在用戶拖動滾動條。由於該事件會連續地大量觸發,所以它的監聽函數之中不應該有非常耗費計算的操作。推薦的做法是使用requestAnimationFrame或setTimeout或使用自定義的throttle函數(節流函數)控制該事件的觸發頻率,然后可以結合customEvent拋出一個新事件(CustomEvent(type,eventInit) 創建一個自定義事件)
resize事件在改變瀏覽器窗口大小時觸發,發生在window、body、frameset對象上面。該事件也會連續地大量觸發,所以最好像上面的scroll事件一樣,通過throttle函數控制事件觸發頻率
以下事件與文檔的URL變化相關:
hashchange事件在URL的hash部分(即#號后面的部分,包括#號)發生變化時觸發。如果老式瀏覽器不支持該屬性,可以通過定期檢查location.hash屬性,模擬該事件,hashchange事件對象除了繼承Event對象,還有oldURL屬性和newURL屬性,分別表示變化前后的URL
popstate事件在瀏覽器的history對象的當前記錄發生顯式切換時觸發。注意,調用history.pushState()或history.replaceState(),並不會觸發popstate事件。該事件只在用戶在history記錄之間顯式切換時觸發,比如鼠標點擊“后退/前進”按鈕,或者在腳本中調用history.back()、history.forward()、history.go()時觸發。該事件對象有一個state屬性,保存history.pushState方法和history.replaceState方法為當前記錄添加的state對象。
以下三個事件屬於文本操作觸發的事件
cut事件:在將選中的內容從文檔中移除,加入剪貼板后觸發。
copy事件:在選中的內容加入剪貼板后觸發。
paste事件:在剪貼板內容被粘貼到文檔后觸發。
這三個事件都有一個clipboardData只讀屬性。該屬性存放剪貼的數據,是一個DataTransfer對象,具體的API接口和操作方法,請參見‘觸摸事件’的DataTransfer對象
焦點事件:
發生在Element節點和document對象上面,與獲得或失去焦點相關。它主要包括以下四個事件。
focus事件:Element節點獲得焦點后觸發,該事件不會冒泡。
blur事件:Element節點失去焦點后觸發,該事件不會冒泡。
focusin事件:Element節點將要獲得焦點時觸發,發生在focus事件之前。該事件會冒泡。Firefox不支持該事件。
focusout事件:Element節點將要失去焦點時觸發,發生在blur事件之前。該事件會冒泡。Firefox不支持該事件。
這四個事件的事件對象,帶有target屬性(返回事件的目標節點)和relatedTarget屬性(返回一個Element節點)。對於focusin事件,relatedTarget屬性表示失去焦點的節點;對於focusout事件,表示將要接受焦點的節點;對於focus和blur事件,該屬性返回null。
由於focus和blur事件不會冒泡,只能在捕獲階段觸發,所以addEventListener方法的第三個參數需要設為true。
三、鼠標事件MouseEvent對象
        構造函數new MouseEvent(typeArg, mouseEventInit);內置的鼠標事件mousedown mouseup click dblclick,mousemove mouseover mouseout,mouseenter mouseleave,contextmenu,wheel
                        altKey,ctrlKey,metaKey,shiftKey屬性返回一個布爾值,表示鼠標事件發生時,是否按下某個鍵;
                        button返回事件的鼠標鍵信息(值為-1,0,1,2之一,可通過switch來選擇執行分之);
                        buttons屬性返回一個3個比特位的值,表示同時按下了哪些鍵
                        clientX,clientY返回鼠標位置相對於瀏覽器窗口左上角的坐標,單位為像素
                        screenX,screenY返回鼠標位置相對於屏幕左上角的坐標,單位為像素
                        movementX,movementY返回一個位移,單位為像素,表示當前位置與上一個mousemove事件之間的距離,在數值上,等於currentEvent.movementX = currentEvent.screenX - previousEvent.screenX
                        relatedTarget屬性返回事件的次要相關節點,即和target屬性對應的節點,如:mouseout target指將要離開的節點,relatedTarget指將要進入的節點。對於那些沒有次要相關節點的事件,該屬性返回null
                         wheel事件是與鼠標滾輪相關的事件,瀏覽器提供一個WheelEvent構造函數new WheelEvent(typeArg, mouseEventInit),deltaX:返回一個數值,表示滾輪的水平滾動量。deltaY:返回一個數值,表示滾輪的垂直滾動量。deltaZ:返回一個數值,表示滾輪的Z軸滾動量。deltaMode:返回一個數值,表示滾動的單位,適用於上面三個屬性。0表示像素,1表示行,2表示頁。
四、鍵盤事件KeyboardEvent對象
        構造函數new KeyboardEvent(typeArg, KeyboardEventInit),內置事件keydown:按下鍵盤時觸發該事件。keypress:只要按下的鍵並非Ctrl、Alt、Shift和Meta,就接着觸發keypress事件。keyup:松開鍵盤時觸發該事件;
                        altKey,ctrlKey,metaKey,shiftKey返回一個布爾值,表示是否按下對應的鍵
                        key屬性返回一個字符串,表示按下的鍵名。如果同時按下一個控制鍵和一個符號鍵,則返回符號鍵的鍵名。比如,按下Ctrl+a,則返回a。如果無法識別鍵名,則返回字符串Unidentified
五、進度事件ProgressEvent對象
        構造函數 new ProgressEvent(type, {lengthComputable: aBooleanValue, loaded: aNumber,total: aNumber})默認值分別為false,0,0,進度事件用來描述一個事件進展的過程,比如XMLHttpRequest對象發出的HTTP請求的過程、<img>、<audio>、<video>、<style>、<link>加載外部資源的過程。下載和上傳都會發生進度事件。
                         lengthComputable:返回一個布爾值,表示當前進度是否具有可計算的長度。如果為false,就表示當前進度無法測量。
                        total:返回一個數值,表示當前進度的總長度。如果是通過HTTP下載某個資源,表示內容本身的長度,不含HTTP頭部的長度。如果lengthComputable屬性為false,則total屬性就無法取得正確的值。
                        loaded:返回一個數值,表示當前進度已經完成的數量。該屬性除以total屬性,就可以得到目前進度的百分比。if (e.lengthComputable) {var percentComplete = e.loaded / e.total; }
        包含以下事件:
 
                        abort事件:當進度事件被中止時觸發。如果發生錯誤,導致進程中止,不會觸發該事件。
 
                        error事件:由於錯誤導致資源無法加載時觸發,不會冒泡。error事件的監聽函數最好放在如img元素的HTML屬性中,這樣才能保證發生加載錯誤時百分之百會執行。
 
                        load事件:進度成功結束時觸發。
 
                        loadstart事件:進度開始時觸發。
 
                        loadend事件:進度停止時觸發,發生順序排在error事件\abort事件\load事件后面。loadend事件的監聽函數可以用來取代abort事件/load事件/error事件的監聽函數,loadend事件本身不提供關於進度結束的原因,但可以用它來做所有進度結束場景都需要做的一些操作。
 
                        progress事件:當操作處於進度之中,由傳輸的數據塊不斷觸發。
                        timeout事件:進度超過限時觸發
                     
六、拖拉事件DragEvent對象
        拖拉指的是,用戶在某個對象上按下鼠標鍵不放,拖動它到另一個位置,然后釋放鼠標鍵,將該對象放在那里。拖拉的對象有好幾種,包括Element節點、圖片、鏈接、選中的文字等等。在HTML網頁中,除了Element節點默認不可以拖拉,其他(圖片、鏈接、選中的文字)都是可以直接拖拉的。為了讓Element節點可拖拉,可以將該節點的draggable屬性設為true。draggable屬性可用於任何Element節點,但是圖片(img元素)和鏈接(a元素)不加這個屬性,就可以拖拉。對於它們,用到這個屬性的時候,往往是將其設為false,防止拖拉。注意,一旦某個Element節點的draggable屬性設為true,就無法再用鼠標選中該節點內部的文字或子節點了。
         當Element節點或選中的文本被拖拉時,就會持續觸發拖拉事件,包括以下一些事件
drag事件:拖拉過程中,在被拖拉的節點上持續觸發。
dragstart事件:拖拉開始時在被拖拉的節點上觸發,該事件的target屬性是被拖拉的節點。通常應該在這個事件的監聽函數中,指定拖拉的數據。
dragend事件:拖拉結束時(釋放鼠標鍵或按下escape鍵)在被拖拉的節點上觸發,該事件的target屬性是被拖拉的節點。它與dragStart事件,在同一個節點上觸發。不管拖拉是否跨窗口,或者中途被取消,dragend事件總是會觸發的。
dragenter事件:拖拉進入當前節點時,在當前節點上觸發,該事件的target屬性是當前節點。通常應該在這個事件的監聽函數中,指定是否允許在當前節點放下(drop)拖拉的數據。如果當前節點沒有該事件的監聽函數,或者監聽函數不執行任何操作,就意味着不允許在當前節點放下數據。在視覺上顯示拖拉進入當前節點,也是在這個事件的監聽函數中設置。
dragover事件:拖拉到當前節點上方時,在當前節點上持續觸發,該事件的target屬性是當前節點。該事件與dragenter事件基本類似,默認會重置當前的拖拉事件的效果(DataTransfer對象的dropEffect屬性)為none,即不允許放下被拖拉的節點,所以如果允許在當前節點drop數據,通常會使用preventDefault方法,取消重置拖拉效果為none。
dragleave事件:拖拉離開當前節點范圍時,在當前節點上觸發,該事件的target屬性是當前節點。在視覺上顯示拖拉離開當前節點,就在這個事件的監聽函數中設置。
drop事件:被拖拉的節點或選中的文本,釋放到目標節點時,在目標節點上觸發。注意,如果當前節點不允許drop,即使在該節點上方松開鼠標鍵,也不會觸發該事件。如果用戶按下Escape鍵,取消這個操作,也不會觸發該事件。該事件的監聽函數負責取出拖拉數據,並進行相關處理。
         關於拖拉事件,有以下幾點注意事項
1.拖拉過程只觸發以上這些拖拉事件,盡管鼠標在移動,但是鼠標事件不會觸發。
2.將文件從操作系統拖拉進瀏覽器,不會觸發dragStart和dragend事件。
3.dragenter和dragover事件的監聽函數,用來指定可以放下(drop)拖拉的數據。由於網頁的大部分區域不適合作為drop的目標節點,所以這兩個事件的默認設置為當前節點不允許drop。如果想要在目標節點上drop拖拉的數據,首先必須阻止這兩個事件的默認行為,或者取消這兩個事件。<div ondragover="return false">或<div ondragover="event.preventDefault()">
        拖拉事件用一個DragEvent對象表示,該對象繼承MouseEvent對象,DragEvent對象只有一個獨有的屬性DataTransfer,其他都是繼承的屬性。DataTransfer屬性用來讀寫拖拉事件中傳輸的數據,所有的拖拉事件都有一個dataTransfer屬性,用來保存需要傳遞的數據,這個屬性的值是一個DataTransfer對象。拖拉的數據保存兩方面的數據:數據的種類(又稱格式)和數據的值。數據的種類是一個MIME字符串,比如 text/plain或者image/jpeg,數據的值是一個字符串;
         DataTransfer對象的屬性
dropEffect屬性設置放下(drop)被拖拉節點時的效果,可能的值包括copy(復制被拖拉的節點)、move(移動被拖拉的節點)、link(創建指向被拖拉的節點的鏈接)、none(無法放下被拖拉的節點)。設置除此以外的值,都是無效的。
effectAllowed屬性設置本次拖拉中允許的效果,可能的值包括copy、move、link、copyLink、copyMove、linkMove、all、none、uninitialized(默認值,等同於all)。如果某種效果是不允許的,用戶就無法在目標節點中達成這種效果。
files屬性是一個FileList對象,包含一組本地文件,可以用來在拖拉操作中傳送。如果本次拖拉不涉及文件,則屬性為空的FileList對象。通過files屬性讀取拖拉文件的信息。如果想要讀取文件內容,就要使用 FileReader對象。
types屬性是一個數組,保存每一次拖拉的數據格式,如‘text/uri-list’
         DataTransfer對象的方法:
setData方法用來設置事件所帶有的指定類型的數據。它接受兩個參數,第一個是數據類型,第二個是具體數據。如果指定的類型在現有數據中不存在,則該類型將寫入types屬性;如果已經存在,在該類型的現有數據將被替換。
event.dataTransfer.setData("text/plain", "Text to drag");
getData方法接受一個字符串(表示數據類型)作為參數,返回事件所帶的指定類型的數據(通常是用setData方法添加的數據)。如果指定類型的數據不存在,則返回空字符串。
event.dataTransfer.getData(types[0]);
clearData方法接受一個字符串(表示數據類型)作為參數,刪除事件所帶的指定類型的數據。如果沒有指定類型,則刪除所有數據。如果指定類型不存在,則原數據不受影響。
event.dataTransfer.clearData("text/uri-list");
setDragImage可以用來自定義這張圖片,它接受三個參數,第一個是img圖片元素或者canvas元素,如果省略或為null則使用被拖動的節點的外觀,第二個和第三個參數為鼠標相對於該圖片左上角的橫坐標和右坐標。
event.dataTransfer.setDragImage(img, 0, 0);

七、觸摸事件:觸摸API由三個對象組成。每 個 Touch 對象代表一個觸點; 每個觸點都由其位置,大小,形狀,壓力大小,和目標 element 描述。 TouchList 對象代表多個觸點的一個列表。
         Touch對象:代表一個觸摸點。觸摸點可能是一根手指,也可能是一根觸摸筆。它有以下屬性
identifier屬性表示Touch實例的獨一無二的識別符。它在整個觸摸過程中保持不變。var id = touchItem.identifier;
screenX屬性和screenY屬性,分別表示觸摸點相對於屏幕左上角的橫坐標和縱坐標,與頁面是否滾動無關;
clientX屬性和clientY屬性,分別表示觸摸點相對於瀏覽器視口左上角的橫坐標和縱坐標,與頁面是否滾動無關
pageX屬性和pageY屬性,分別表示觸摸點相對於當前頁面左上角的橫坐標和縱坐標,包含了頁面滾動帶來的位移
radiusX屬性和radiusY屬性,分別返回觸摸點周圍受到影響的橢圓范圍的X軸和Y軸,單位為像素。
rotationAngle屬性表示觸摸區域的橢圓的旋轉角度,單位為度數,在0到90度之間。指尖接觸屏幕,觸摸范圍會形成一個橢圓,這三個屬性就用來描述這個橢圓區域。
force屬性返回一個0到1之間的數值,表示觸摸壓力。0代表沒有壓力,1代表硬件所能識別的最大壓力。
target屬性返回一個Element節點,代表觸摸發生的那個節點。當這個觸點最開始被跟蹤時(在 touchstart 事件中), 觸點位於的HTML元素. 哪怕在觸點移動過程中, 觸點的位置已經離開了這個元素的有效交互區域, 或者這個元素已經被從文檔中移除. 需要注意的是, 如果這個元素在觸摸過程中被移除, 這個事件仍然會指向它, 但是不會再冒泡這個事件到 window 或 document 對象. 因此, 如果有元素在觸摸過程中可能被移除, 最佳實踐是將觸摸事件的監聽器綁定到這個元素本身, 防止元素被移除后, 無法再從它的上一級元素上偵測到從該元素冒泡的事件. 只讀屬性.
        TouchList對象:是一個類似數組的對象,成員是與某個觸摸事件相關的所有觸摸點。比如,用戶用三根手指觸摸,產生的TouchList對象就有三個成員,每根手指對應一個Touch對象。TouchList實例的length屬性,返回TouchList對象的成員數量。TouchList實例的identifiedTouch方法和item方法,分別使用id屬性和索引值(從0開始)作為參數,取出指定的Touch對象。
        TouchEvent對象:表示觸摸引發的事件。除了被繼承的屬性以外,它還有一些自己的屬性。
鍵盤相關屬性altKey、ctrlKey、metaKey、shiftKey都為只讀屬性,返回一個布爾值,表示觸摸的同時,是否按下某個鍵
changedTouches屬性返回一個TouchList對象,包含了由當前觸摸事件引發的所有Touch對象(即相關的觸摸點)。它包含了代表所有從上一次觸摸事件到此次事件過程中,狀態發生了改變的觸點的 Touch 對象。只讀屬性。
targetTouches屬性返回一個TouchList對象,包含了觸摸的目標Element節點內部,所有仍然處於活動狀態的觸摸點。
touches屬性返回一個TouchList對象,包含了所有當前接觸觸摸平面的觸點的 Touch 對象,無論它們的起始於哪個 element 上,也無論它們狀態是否發生了變化。只讀屬性
type屬性指此次觸摸事件的類型。
target屬性此次觸摸事件的目標 element 。這個目標元素對應 TouchEvent.changedTouches 中的觸點的起始元素(在之后的事件類型中有說明),但是請注意:此次事件中其他的觸點的起始元素可能有所不同。以防萬一,應使用和每一個單獨觸點相關聯的目標 。
             通過TouchEvent.type屬性可以查看觸摸事件的種類
touchstart:用戶接觸觸摸屏時觸發,它的target屬性返回發生觸摸的Element節點。
touchend:用戶不再接觸觸摸屏時(或者移出屏幕邊緣時)觸發,它的target屬性與touchstart事件的target屬性是一致的,它的changedTouches屬性返回一個TouchList對象,包含所有不再觸摸的觸摸點(Touch對象)。
touchmove:用戶移動觸摸點時觸發,它的target屬性與touchstart事件的target屬性一致。如果觸摸的半徑、角度、力度發生變化,也會觸發該事件。
touchenter當觸點進入某個 element 時觸發。此事件沒有冒泡過程。
touchleave當觸點離開某個 element 時觸發。此事件沒有冒泡過程。
touchcancel:當觸點由於某些原因被中斷時觸發。有幾種可能的原因如下(具體的原因根據不同的設備和瀏覽器有所不同):1.由於某個事件取消了觸摸:例如觸摸過程被一個模態的彈出框打斷。2.觸點離開了文檔窗口,而進入了瀏覽器的界面元素、插件或者其他外部內容區域。3.當用戶產生的觸點個數超過了設備支持的個數,從而導致 TouchList 中最早的 Touch 對象被取消。
function handleMove(evt) {
  evt.preventDefault(); // 阻止瀏覽器繼續處理觸摸事件,也阻止發出鼠標事件
  var touches = evt.changedTouches;
  for (var i = 0; i < touches.length; i++) {
    var id = touches[i].identifier;
    var touch = touches.identifiedTouch(id);
    console.log(touch.pageX, touch.pageY);
  }
}
八、自定義事件和事件模擬
用戶可以自定義事件,然后手動觸發:
var event = new Event('build');
elem.addEventListener('build', function (e) { ... }, false);
elem.dispatchEvent(event);
Event構造函數只能指定事件名,不能在事件上綁定數據。如果需要在觸發事件的同時,傳入指定的數據,需要使用CustomEvent構造函數生成自定義的事件對象。
var myEvent = new CustomEvent("myevent", {
  detail: {
    foo: "bar"
  },
  bubbles: true,
  cancelable: false
});
el.addEventListener('myevent', function(event) {
  console.log('Hello ' + event.detail.foo);
});
el.dispatchEvent(myEvent);
IE不支持以上方法,可以用下面的墊片函數模擬:
(function () {
  function CustomEvent ( event, params ) {
    params = params || { bubbles: false, cancelable: false, detail: undefined };
    var evt = document.createEvent( 'CustomEvent' );
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
    return evt;
   }
  CustomEvent.prototype = window.Event.prototype;
  window.CustomEvent = CustomEvent;
})();
事件的模擬:
有時,需要在腳本中模擬觸發某種類型的事件,這時就必須使用這種事件的構造函數。下面是一個通過MouseEvent構造函數,模擬觸發click鼠標事件的例子。
function simulateClick() {
  var event = new MouseEvent('click', {
    'bubbles': true,
    'cancelable': true
  });
  var cb = document.getElementById('checkbox');
  cb.dispatchEvent(event);
}
自定義事件的老式寫法
document.createEvent方法用來新建指定類型的事件。它所生成的Event實例,可以傳入dispatchEvent方法。createEvent方法接受一個字符串作為參數,可能的值參見下表“數據類型”一欄。使用了某一種“事件類型”,就必須使用對應的事件初始化方法。如:initUIEvent、initMouseEvent、initMutationEvent、initEvent、initCustomEvent、initKeyEvent
事件對象的initEvent方法,用來初始化事件對象,還能向事件對象添加屬性。該方法的參數必須是一個使用Document.createEvent()生成的Event實例,而且必須在dispatchEvent方法之前調用。
var event = document.createEvent('Event');
event.initEvent('my-custom-event', true, true, {foo:'bar'});
someElement.dispatchEvent(event);
事件模擬的老式寫法
事件模擬的非標准做法是,對document.createEvent方法生成的事件對象,使用對應的事件初始化方法進行初始化。比如,click事件對象屬於MouseEvent對象,也屬於UIEvent對象,因此要用initMouseEvent方法或initUIEvent方法進行初始化,如模擬鼠標事件:
initMouseEvent方法用來初始化Document.createEvent方法新建的鼠標事件。該方法必須在事件新建(document.createEvent方法)之后、觸發(dispatchEvent方法)之前調用。initMouseEvent方法有很長的參數。
event.initMouseEvent(type, canBubble, cancelable, view,
  detail, screenX, screenY, clientX, clientY,
  ctrlKey, altKey, shiftKey, metaKey,
  button, relatedTarget
);
上面這些參數的含義,參見MouseEvent構造函數的部分。
模仿並觸發click事件的寫法如下。
var simulateDivClick = document.createEvent('MouseEvents');
simulateDivClick.initMouseEvent('click',true,true,
  document.defaultView,0,0,0,0,0,false,
  false,false,0,null,null
);
divElement.dispatchEvent(simulateDivClick);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM