摘要:之前寫(xiě)過(guò)一篇瀏覽器事件的相關(guān)操作和事件運(yùn)行的原理瀏覽器事件解析。注意,頁(yè)面從瀏覽器緩存加載,并不會(huì)觸發(fā)事件。事件有一個(gè)屬性,返回一個(gè)布爾值。此外,不支持事件,可以使用事件代替。
之前寫(xiě)過(guò)一篇瀏覽器事件的相關(guān)操作和事件運(yùn)行的原理——JavaScript瀏覽器事件解析。這一篇主要寫(xiě)一些常用的事件及一些可能的坑。
表單事件 鍵盤(pán)事件當(dāng) , 的值發(fā)生變化時(shí)觸發(fā)。此外,打開(kāi) contenteditable 屬性的元素,只要值發(fā)生變化,也會(huì)觸發(fā) input 事件。input 事件的一個(gè)特點(diǎn),就是會(huì)連續(xù)觸發(fā),比如用戶每次按下一次按鍵,就會(huì)觸發(fā)一次input事件。
此類(lèi)事件包括: keydown, keyup,
鼠標(biāo)事件select 事件當(dāng)在, 中選中文本時(shí)觸發(fā)
change 事件當(dāng), , 的值發(fā)生變化時(shí)觸發(fā)。它與 input 事件的最大不同,就是不會(huì)連續(xù)觸發(fā),只有當(dāng)全部修改完成時(shí)才會(huì)觸發(fā),而且input事件必然會(huì)引發(fā)change事件。具體來(lái)說(shuō),分成以下幾種情況:
激活單選框(radio)或復(fù)選框(checkbox)時(shí)觸發(fā)。
用戶提交時(shí)觸發(fā)。比如,從下列列表(select)完成選擇,在日期或文件輸入框完成選擇。
當(dāng)文本框或textarea元素的值發(fā)生改變,并且喪失焦點(diǎn)時(shí)觸發(fā)。
reset事件當(dāng)表單重置(所有表單成員變回默認(rèn)值)時(shí)由form元素觸發(fā)。
submit事件當(dāng)表單數(shù)據(jù)向服務(wù)器提交時(shí)由form元素觸發(fā)。
文檔事件: beforeunloadbeforeunload 事件當(dāng)窗口將要關(guān)閉,或者 document 和網(wǎng)頁(yè)資源將要卸載時(shí)觸發(fā)。它可以用來(lái)防止用戶不當(dāng)心關(guān)閉網(wǎng)頁(yè)。該事件的默認(rèn)動(dòng)作就是關(guān)閉當(dāng)前窗口或文檔。如果在監(jiān)聽(tīng)函數(shù)中,調(diào)用了 event.preventDefault(),或者對(duì)事件對(duì)象的 returnValue 屬性賦予一個(gè)非空的值,就會(huì)自動(dòng)跳出一個(gè)確認(rèn)框,讓用戶確認(rèn)是否關(guān)閉網(wǎng)頁(yè)。如果用戶點(diǎn)擊“取消”按鈕,網(wǎng)頁(yè)就不會(huì)關(guān)閉。監(jiān)聽(tīng)函數(shù)所返回的字符串,會(huì)顯示在確認(rèn)對(duì)話框之中:
window.addEventListener("beforeunload", function(event) { if(event.preventDefault){ event.preventDefault(); } else { event.returnValue = "你確認(rèn)要離開(kāi)嗎?"; } });unload 與 load
unload 事件在窗口關(guān)閉或者 document 對(duì)象將要卸載時(shí)觸發(fā),發(fā)生在 window, body, frameset 等對(duì)象上面。它的觸發(fā)順序排在 beforeunload, pagehide 事件后面。unload 事件只在頁(yè)面沒(méi)有被瀏覽器緩存時(shí)才會(huì)觸發(fā),換言之,如果通過(guò)按下“前進(jìn)/后退”導(dǎo)致頁(yè)面卸載,并不會(huì)觸發(fā) unload 事件。當(dāng) unload 事件發(fā)生時(shí),document 對(duì)象處于一個(gè)特殊狀態(tài)。所有資源依然存在,但是對(duì)用戶來(lái)說(shuō)都不可見(jiàn),UI互動(dòng)(window.open, alert, confirm方法等)全部無(wú)效。這時(shí)即使拋出錯(cuò)誤,也不能停止文檔的卸載。
load事件在頁(yè)面加載成功時(shí)觸發(fā),error事件在頁(yè)面加載失敗時(shí)觸發(fā)。注意,頁(yè)面從瀏覽器緩存加載,并不會(huì)觸發(fā)load事件。
這兩個(gè)事件實(shí)際上屬于進(jìn)度事件,不僅發(fā)生在 document 對(duì)象,還發(fā)生在各種外部資源上面。瀏覽網(wǎng)頁(yè)就是一個(gè)加載各種資源的過(guò)程,圖像(image), 樣式表(style sheet), 腳本(script), 視頻(video), 音頻(audio), Ajax請(qǐng)求(XMLHttpRequest)等等。這些資源和document對(duì)象, window對(duì)象, XMLHttpRequestUpload對(duì)象,都會(huì)觸發(fā) load 事件和 error 事件。
pageshow 與 pagehidepageshow事件,pagehide事件: 默認(rèn)情況下,瀏覽器會(huì)在當(dāng)前會(huì)話(session)緩存頁(yè)面,當(dāng)用戶點(diǎn)擊“前進(jìn)/后退”按鈕時(shí),瀏覽器就會(huì)從緩存中加載頁(yè)面。
pageshow 事件在頁(yè)面加載時(shí)觸發(fā),包括第一次加載和從緩存加載兩種情況。如果要指定頁(yè)面每次加載(不管是不是從瀏覽器緩存)時(shí)都運(yùn)行的代碼,可以放在這個(gè)事件的監(jiān)聽(tīng)函數(shù)。第一次加載時(shí),它的觸發(fā)順序排在load事件后面。從緩存加載時(shí),load 事件不會(huì)觸發(fā),因?yàn)榫W(wǎng)頁(yè)在緩存中的樣子通常是 load 事件的監(jiān)聽(tīng)函數(shù)運(yùn)行后的樣子,所以不必重復(fù)執(zhí)行。同理,如果是從緩存中加載頁(yè)面,網(wǎng)頁(yè)內(nèi)初始化的 JavaScript 腳本(比如 DOMContentLoaded 事件的監(jiān)聽(tīng)函數(shù))也不會(huì)執(zhí)行。pageshow 事件有一個(gè) persisted 屬性,返回一個(gè)布爾值。頁(yè)面第一次加載時(shí),這個(gè)屬性是false;當(dāng)頁(yè)面從緩存加載時(shí),這個(gè)屬性是true。
document.onpageshow = function(event){} if(event.persisted){ //如果存緩存加載 } }
同樣的,將這個(gè)屬性設(shè)為 true,就表示頁(yè)面要保存在緩存中;設(shè)為 false ,表示網(wǎng)頁(yè)不保存在緩存中,這時(shí)如果設(shè)置了 unload 事件的監(jiān)聽(tīng)函數(shù),該函數(shù)將在 pagehide 事件后立即運(yùn)行。如果頁(yè)面包含 frame ,則 frame 頁(yè)面的 pageshow 事件和 pagehide 事件,都會(huì)在主頁(yè)面之前觸發(fā)。
DOMContentLoaded 和 readystatechangeDOMContentLoaded 事件當(dāng) HTML 文檔下載并解析完成以后,就會(huì)在 document 對(duì)象上觸發(fā) DOMContentLoaded 事件。這時(shí),僅僅完成了 HTML 文檔的解析(整張頁(yè)面的DOM生成),所有外部資源(樣式表, 腳本, iframe等等)可能還沒(méi)有下載結(jié)束。也就是說(shuō),這個(gè)事件比 load 事件,發(fā)生時(shí)間早得多。注意,網(wǎng)頁(yè)的 JavaScript 腳本是同步執(zhí)行的,所以定義 DOMContentLoaded 事件的監(jiān)聽(tīng)函數(shù),應(yīng)該放在所有腳本的最前面。否則腳本一旦發(fā)生堵塞,將推遲觸發(fā) DOMContentLoaded 事件。此外,IE8 不支持 DOMContentLoaded 事件,可以使用 readystatechange 事件代替。
readystatechange 事件發(fā)生在 Document 對(duì)象和 XMLHttpRequest 對(duì)象,當(dāng)它的 readyState 屬性發(fā)生變化時(shí)觸發(fā)。
其他文檔級(jí)事件上面重點(diǎn)提到了 DOMContentLoaded, readystatechange, pageshow, pagehide, unload, load 和 beforeunload 事件,此外還有一下事件:
onafterprint: 文檔打印之后運(yùn)行的腳本
onbeforeprint: 文檔打印之前運(yùn)行的腳本
onbeforeunload: 文檔卸載之前運(yùn)行的腳本(上文已涉及)
onerror: 在錯(cuò)誤發(fā)生時(shí)運(yùn)行的腳本
onhaschange: 當(dāng)文檔已改變時(shí)運(yùn)行的腳本
onload: 頁(yè)面結(jié)束加載之后觸發(fā)(上文已涉及)
onmessage: 在消息被觸發(fā)時(shí)運(yùn)行的腳本
onoffline: 當(dāng)文檔離線時(shí)運(yùn)行的腳本
ononline: 當(dāng)文檔上線時(shí)運(yùn)行的腳本
onpagehide: 當(dāng)窗口隱藏時(shí)運(yùn)行的腳本(上文已涉及)
onpageshow: 當(dāng)窗口成為可見(jiàn)時(shí)運(yùn)行的腳本(上文已涉及)
onpopstate: 當(dāng)窗口歷史記錄改變時(shí)運(yùn)行的腳本
onredo: 當(dāng)文檔執(zhí)行撤銷(xiāo)(redo)時(shí)運(yùn)行的腳本
onresize: 當(dāng)瀏覽器窗口被調(diào)整大小時(shí)觸發(fā)
onstorage: 在 Web Storage 區(qū)域更新后運(yùn)行的腳本
onundo: 在文檔執(zhí)行 undo 時(shí)運(yùn)行的腳本
onscroll: 事件在文檔或文檔元素滾動(dòng)時(shí)執(zhí)行腳本
鼠標(biāo)事件 與 MouseEvent對(duì)象new MouseEvent(typeArg, mouseEventInit);
內(nèi)置的鼠標(biāo)事件包括:
mousedown: 按下鼠標(biāo)
mouseup: 鼠標(biāo)抬起
click: 點(diǎn)擊
dblclick: 雙擊
mousemove: 鼠標(biāo)移動(dòng)
mouseover: 鼠標(biāo)移入,冒泡
mouseout: 鼠標(biāo)移出,冒泡
mouseenter: 鼠標(biāo)移入,不冒泡
mouseleave: 鼠標(biāo)移出,不冒泡
contextmenu: 右鍵菜單
wheel: 滾輪事件
其具有如下常用屬性:
altKey,ctrlKey,metaKey,shiftKey屬性返回一個(gè)布爾值,表示鼠標(biāo)事件發(fā)生時(shí),是否按下某個(gè)鍵;
button 返回事件的鼠標(biāo)鍵信息, 值為0(左鍵), 1或4(中鍵, 4為IE中的值),2(右鍵),可通過(guò)switch來(lái)選擇執(zhí)行分之);
buttons 屬性返回一個(gè)3個(gè)比特位的值,表示同時(shí)按下了哪些鍵
clientX,clientY 返回鼠標(biāo)位置相對(duì)于瀏覽器窗口左上角的坐標(biāo),單位為像素
screenX,screenY 返回鼠標(biāo)位置相對(duì)于屏幕左上角的坐標(biāo),單位為像素
movementX,movementY 返回一個(gè)位移,單位為像素,表示當(dāng)前位置與上一個(gè) mousemove 事件之間的距離,在數(shù)值上:
currentEvent.movementX = currentEvent.screenX - previousEvent.screenX
currentEvent.movementY = currentEvent.screenY - previousEvent.screenY
relatedTarget屬性返回事件的次要相關(guān)節(jié)點(diǎn),即和target屬性對(duì)應(yīng)的節(jié)點(diǎn),如: mouseout target 指將要離開(kāi)的節(jié)點(diǎn),relatedTarget 指將要進(jìn)入的節(jié)點(diǎn)。對(duì)于那些沒(méi)有次要相關(guān)節(jié)點(diǎn)的事件,該屬性返回null
wheel 事件是與鼠標(biāo)滾輪相關(guān)的事件,瀏覽器提供一個(gè) WheelEvent 構(gòu)造函數(shù) new WheelEvent(typeArg, mouseEventInit)
deltaX: 返回一個(gè)數(shù)值,表示滾輪的水平滾動(dòng)量
deltaY: 返回一個(gè)數(shù)值,表示滾輪的垂直滾動(dòng)量
deltaZ: 返回一個(gè)數(shù)值,表示滾輪的Z軸滾動(dòng)量
deltaMode: 返回一個(gè)數(shù)值,表示滾動(dòng)的單位,適用于上面三個(gè)屬性。0表示像素,1表示行,2表示頁(yè)
鍵盤(pán)事件 KeyboardEvent 對(duì)象構(gòu)造函數(shù) new KeyboardEvent(typeArg, KeyboardEventInit)
鍵盤(pán)事件包括keydown(按下鍵盤(pán)時(shí)觸發(fā)該事件),keypress(只要按下的鍵并非Ctrl, Alt, Shift和Meta,就接著觸發(fā)keypress事件), keyup(松開(kāi)鍵盤(pán)時(shí)觸發(fā)該事件)
altKey,ctrlKey,metaKey,shiftKey: 返回一個(gè)布爾值,表示是否按下對(duì)應(yīng)的鍵
key: 返回一個(gè)字符串,表示按下的鍵名。如果同時(shí)按下一個(gè)控制鍵和一個(gè)符號(hào)鍵,則返回符號(hào)鍵的鍵名
keyCode: 返回按鍵的 ASCII 碼,注意: 這里是不區(qū)分大小寫(xiě)的,A鍵不論輸出 A 還是 a keyCode 都是68。在 IE 中使用 witch 屬性
進(jìn)度事件 ProgressEvent對(duì)象new ProgressEvent(type, { lengthComputable: aBooleanValue, // false as default loaded: aNumber, // 0 as default total: aNumber // 0 as default });
進(jìn)度事件用來(lái)描述一個(gè)事件進(jìn)展的過(guò)程,比如XMLHttpRequest對(duì)象發(fā)出的HTTP請(qǐng)求的過(guò)程, , , , , 加載外部資源的過(guò)程,包括下載和上傳。通常包括以下事件:
abort事件: 當(dāng)進(jìn)度事件被中止時(shí)觸發(fā)。如果發(fā)生錯(cuò)誤,導(dǎo)致進(jìn)程中止,不會(huì)觸發(fā)該事件。
error事件: 由于錯(cuò)誤導(dǎo)致資源無(wú)法加載時(shí)觸發(fā),不會(huì)冒泡。error 事件的監(jiān)聽(tīng)函數(shù)最好放在如 img 元素的 HTML 屬性中。
load事件: 進(jìn)度成功結(jié)束時(shí)觸發(fā)。
loadstart事件: 進(jìn)度開(kāi)始時(shí)觸發(fā)。
loadend事件: 進(jìn)度停止時(shí)觸發(fā),發(fā)生順序排在error事件abort事件load事件后面。loadend事件的監(jiān)聽(tīng)函數(shù)可以用來(lái)取代abort事件/load事件/error事件的監(jiān)聽(tīng)函數(shù),loadend事件本身不提供關(guān)于進(jìn)度結(jié)束的原因,但可以用它來(lái)做所有進(jìn)度結(jié)束場(chǎng)景都需要做的一些操作。
progress事件: 當(dāng)操作處于進(jìn)度之中,由傳輸?shù)臄?shù)據(jù)塊不斷觸發(fā)。
timeout事件: 進(jìn)度超過(guò)限時(shí)觸發(fā)
這類(lèi)事件具有以下屬性:
lengthComputable: 返回一個(gè)布爾值,表示當(dāng)前進(jìn)度是否具有可計(jì)算的長(zhǎng)度。如果為false,就表示當(dāng)前進(jìn)度無(wú)法測(cè)量。
total: 返回一個(gè)數(shù)值,表示當(dāng)前進(jìn)度的總長(zhǎng)度。如果是通過(guò) HTTP 下載某個(gè)資源,表示內(nèi)容本身的長(zhǎng)度,不含 HTTP 頭部的長(zhǎng)度。如果 lengthComputable 屬性為 false,則 total 屬性就無(wú)法取得正確的值。
loaded: 返回一個(gè)數(shù)值,表示當(dāng)前進(jìn)度已經(jīng)完成的數(shù)量。該屬性除以total屬性,就可以得到目前進(jìn)度的百分比。
//進(jìn)度計(jì)算 if (e.lengthComputable){ var percentComplete = e.loaded / e.total; }拖拽事件 DragEvent 對(duì)象
new DragEvent(type, DragEventInit);
拖拽指的是,用戶在某個(gè)對(duì)象上按下鼠標(biāo)鍵不放,拖動(dòng)它到另一個(gè)位置,然后釋放鼠標(biāo)鍵,將該對(duì)象放在那里。拖拽的對(duì)象有好幾種,包括 Element 節(jié)點(diǎn), 圖片, 鏈接, 選中的文字等等。在 HTML 網(wǎng)頁(yè)中,除了 Element 節(jié)點(diǎn)默認(rèn)不可以拖拽,其他(圖片, 鏈接, 選中的文字)都是可以直接拖拽的。為了讓 Element 節(jié)點(diǎn)可拖拽,可以將該節(jié)點(diǎn)的 draggable 屬性設(shè)為 true。draggable 屬性可用于任何 Element 節(jié)點(diǎn),但是圖片(img 元素)和鏈接(a 元素)不加這個(gè)屬性,就可以拖拽。對(duì)于它們,用到這個(gè)屬性的時(shí)候,往往是將其設(shè)為 false,防止拖拽。注意,一旦某個(gè) Element 節(jié)點(diǎn)的 draggable 屬性設(shè)為 true,就無(wú)法再用鼠標(biāo)選中該節(jié)點(diǎn)內(nèi)部的文字或子節(jié)點(diǎn)了。
當(dāng)Element節(jié)點(diǎn)或選中的文本被拖拽時(shí),就會(huì)持續(xù)觸發(fā)拖拽事件,包括以下一些事件:
drag事件: 拖拽過(guò)程中,在被拖拽的節(jié)點(diǎn)上持續(xù)觸發(fā)。
dragstart事件: 拖拽開(kāi)始時(shí)在被拖拽的節(jié)點(diǎn)上觸發(fā),該事件的target屬性是被拖拽的節(jié)點(diǎn)。通常應(yīng)該在這個(gè)事件的監(jiān)聽(tīng)函數(shù)中,指定拖拽的數(shù)據(jù)。
dragend事件: 拖拽結(jié)束時(shí)(釋放鼠標(biāo)鍵或按下escape鍵)在被拖拽的節(jié)點(diǎn)上觸發(fā),該事件的target屬性是被拖拽的節(jié)點(diǎn)。它與dragStart事件,在同一個(gè)節(jié)點(diǎn)上觸發(fā)。不管拖拽是否跨窗口,或者中途被取消,dragend事件總是會(huì)觸發(fā)的。
dragenter事件: 拖拽進(jìn)入當(dāng)前節(jié)點(diǎn)時(shí),在當(dāng)前節(jié)點(diǎn)上觸發(fā),該事件的target屬性是當(dāng)前節(jié)點(diǎn)。通常應(yīng)該在這個(gè)事件的監(jiān)聽(tīng)函數(shù)中,指定是否允許在當(dāng)前節(jié)點(diǎn)放下(drop)拖拽的數(shù)據(jù)。如果當(dāng)前節(jié)點(diǎn)沒(méi)有該事件的監(jiān)聽(tīng)函數(shù),或者監(jiān)聽(tīng)函數(shù)不執(zhí)行任何操作,就意味著不允許在當(dāng)前節(jié)點(diǎn)放下數(shù)據(jù)。在視覺(jué)上顯示拖拽進(jìn)入當(dāng)前節(jié)點(diǎn),也是在這個(gè)事件的監(jiān)聽(tīng)函數(shù)中設(shè)置。
dragover事件: 拖拽到當(dāng)前節(jié)點(diǎn)上方時(shí),在當(dāng)前節(jié)點(diǎn)上持續(xù)觸發(fā),該事件的target屬性是當(dāng)前節(jié)點(diǎn)。該事件與dragenter事件基本類(lèi)似,默認(rèn)會(huì)重置當(dāng)前的拖拽事件的效果(DataTransfer對(duì)象的dropEffect屬性)為none,即不允許放下被拖拽的節(jié)點(diǎn),所以如果允許在當(dāng)前節(jié)點(diǎn)drop數(shù)據(jù),通常會(huì)使用preventDefault方法,取消重置拖拽效果為none。
dragleave事件: 拖拽離開(kāi)當(dāng)前節(jié)點(diǎn)范圍時(shí),在當(dāng)前節(jié)點(diǎn)上觸發(fā),該事件的target屬性是當(dāng)前節(jié)點(diǎn)。在視覺(jué)上顯示拖拽離開(kāi)當(dāng)前節(jié)點(diǎn),就在這個(gè)事件的監(jiān)聽(tīng)函數(shù)中設(shè)置。
drop事件: 被拖拽的節(jié)點(diǎn)或選中的文本,釋放到目標(biāo)節(jié)點(diǎn)時(shí),在目標(biāo)節(jié)點(diǎn)上觸發(fā)。注意,如果當(dāng)前節(jié)點(diǎn)不允許drop,即使在該節(jié)點(diǎn)上方松開(kāi)鼠標(biāo)鍵,也不會(huì)觸發(fā)該事件。如果用戶按下Escape鍵,取消這個(gè)操作,也不會(huì)觸發(fā)該事件。該事件的監(jiān)聽(tīng)函數(shù)負(fù)責(zé)取出拖拽數(shù)據(jù),并進(jìn)行相關(guān)處理。
關(guān)于拖拽事件,有以下幾點(diǎn)注意事項(xiàng):
拖拽過(guò)程只觸發(fā)以上這些拖拽事件,盡管鼠標(biāo)在移動(dòng),但是鼠標(biāo)事件不會(huì)觸發(fā)。
將文件從操作系統(tǒng)拖拽進(jìn)瀏覽器,不會(huì)觸發(fā) dragStart 和 dragend 事件。
dragenter 和 dragover 事件的監(jiān)聽(tīng)函數(shù),用來(lái)指定可以放下(drop)拖拽的數(shù)據(jù)。由于網(wǎng)頁(yè)的大部分區(qū)域不適合作為 drop 的目標(biāo)節(jié)點(diǎn),所以這兩個(gè)事件的默認(rèn)設(shè)置為當(dāng)前節(jié)點(diǎn)不允許 drop。如果想要在目標(biāo)節(jié)點(diǎn)上 drop 拖拽的數(shù)據(jù),首先必須阻止這兩個(gè)事件的默認(rèn)行為,或者取消這兩個(gè)事件。
//或拖拽事件用一個(gè) DragEvent 對(duì)象表示,該對(duì)象繼承 MouseEvent 對(duì)象,DragEvent 對(duì)象只有一個(gè)獨(dú)有的屬性 dataTransfer,其他都是繼承的屬性。dataTransfer 屬性用來(lái)讀寫(xiě)拖拽事件中傳輸?shù)臄?shù)據(jù),所有的拖拽事件都有一個(gè) dataTransfer 屬性,用來(lái)保存需要傳遞的數(shù)據(jù),這個(gè)屬性的值是一個(gè) DataTransfer 對(duì)象。拖拽的數(shù)據(jù)保存兩方面的數(shù)據(jù): 數(shù)據(jù)的種類(lèi)(又稱格式)和數(shù)據(jù)的值。數(shù)據(jù)的種類(lèi)是一個(gè)MIME字符串,比如 text/plain 或者 image/jpg,數(shù)據(jù)的值是一個(gè)字符串;
dataTransfer 對(duì)象的屬性的值是一個(gè)對(duì)象,其中包括以下屬性:
dropEffect 屬性: 設(shè)置放下(drop)被拖拽節(jié)點(diǎn)時(shí)的效果,可能的值包括 copy(復(fù)制被拖拽的節(jié)點(diǎn)), move(移動(dòng)被拖拽的節(jié)點(diǎn)), link(創(chuàng)建指向被拖拽的節(jié)點(diǎn)的鏈接), none(無(wú)法放下被拖拽的節(jié)點(diǎn))。設(shè)置除此以外的值,都是無(wú)效的。
effectAllowed 屬性: 設(shè)置本次拖拽中允許的效果,可能的值包括 copy, move, link, copyLink, copyMove, linkMove, all, none, uninitialized(默認(rèn)值,等同于 all)。如果某種效果是不允許的,用戶就無(wú)法在目標(biāo)節(jié)點(diǎn)中達(dá)成這種效果。
files 屬性: 是一個(gè) FileList 對(duì)象,包含一組本地文件,可以用來(lái)在拖拽操作中傳送。如果本次拖拽不涉及文件,則屬性為空的 FileList 對(duì)象。通過(guò)files屬性讀取拖拽文件的信息。如果想要讀取文件內(nèi)容,就要使用 FileReader 對(duì)象。
types 屬性: 是一個(gè)數(shù)組,保存每一次拖拽的數(shù)據(jù)格式,如"text/uri-list"
setData() 方法: 用來(lái)設(shè)置事件所帶有的指定類(lèi)型的數(shù)據(jù)。它接受兩個(gè)參數(shù),第一個(gè)是數(shù)據(jù)類(lèi)型,第二個(gè)是具體數(shù)據(jù)。如果指定的類(lèi)型在現(xiàn)有數(shù)據(jù)中不存在,則該類(lèi)型將寫(xiě)入types屬性;如果已經(jīng)存在,在該類(lèi)型的現(xiàn)有數(shù)據(jù)將被替換。
event.dataTransfer.setData("text/plain", "Text to drag");getData() 方法接受一個(gè)字符串(表示數(shù)據(jù)類(lèi)型)作為參數(shù),返回事件所帶的指定類(lèi)型的數(shù)據(jù)(通常是用 setData 方法添加的數(shù)據(jù))。如果指定類(lèi)型的數(shù)據(jù)不存在,則返回空字符串。
event.dataTransfer.getData(types[0]);clearData() 方法接受一個(gè)字符串(表示數(shù)據(jù)類(lèi)型)作為參數(shù),刪除事件所帶的指定類(lèi)型的數(shù)據(jù)。如果沒(méi)有指定類(lèi)型,則刪除所有數(shù)據(jù)。如果指定類(lèi)型不存在,則原數(shù)據(jù)不受影響。
event.dataTransfer.clearData("text/uri-list");setDragImage() 可以用來(lái)自定義這張圖片,它接受三個(gè)參數(shù),第一個(gè)是img圖片元素或者canvas元素,如果省略或?yàn)閚ull則使用被拖動(dòng)的節(jié)點(diǎn)的外觀,第二個(gè)和第三個(gè)參數(shù)為鼠標(biāo)相對(duì)于該圖片左上角的橫坐標(biāo)和右坐標(biāo)。
event.dataTransfer.setDragImage(img, 0, 0);觸摸事件new Touch(touchInit);觸摸事件包括以下5種:
touchstart: 用戶接觸觸摸屏?xí)r觸發(fā),它的 target 屬性返回發(fā)生觸摸的 Element 節(jié)點(diǎn)(IE10+中使用 mspointerdown 事件);
touchend: 用戶不再接觸觸摸屏?xí)r(或者移出屏幕邊緣時(shí))觸發(fā),它的 target 屬性與 touchstart 事件的 target 屬性是一致的,它的 changedTouches 屬性返回一個(gè)TouchList對(duì)象,包含所有不再觸摸的觸摸點(diǎn)(Touch對(duì)象)(IE10+中使用 mspointerup 事件);
touchmove: 用戶移動(dòng)觸摸點(diǎn)時(shí)觸發(fā),它的 target 屬性與 touchstart 事件的 target 屬性一致。如果觸摸的半徑, 角度, 力度發(fā)生變化,也會(huì)觸發(fā)該事件。(IE10+中使用 mspointermove 事件);
touchenter: 當(dāng)觸點(diǎn)進(jìn)入某個(gè) element 時(shí)觸發(fā)。此事件沒(méi)有冒泡過(guò)程。(IE10+中使用 mspointerover 事件);
touchleave: 當(dāng)觸點(diǎn)離開(kāi)某個(gè) element 時(shí)觸發(fā)。此事件沒(méi)有冒泡過(guò)程。(IE10+中使用 mspointerout 事件);
touchcancel: 當(dāng)觸點(diǎn)由于某些原因被中斷時(shí)觸發(fā)。有幾種可能的原因如下(具體的原因根據(jù)不同的設(shè)備和瀏覽器有所不同):(IE10+中沒(méi)有對(duì)應(yīng)事件);
由于某個(gè)事件取消了觸摸: 例如觸摸過(guò)程被一個(gè)模態(tài)的彈出框或電話打斷;
觸點(diǎn)離開(kāi)了文檔窗口,而進(jìn)入了瀏覽器的界面元素, 插件或者其他外部?jī)?nèi)容區(qū)域;
當(dāng)用戶產(chǎn)生的觸點(diǎn)個(gè)數(shù)超過(guò)了設(shè)備支持的個(gè)數(shù),從而導(dǎo)致 TouchList 中最早的 Touch 對(duì)象被取消。
觸摸 API 由三個(gè)對(duì)象組成。每個(gè) Touch 對(duì)象代表一個(gè)觸點(diǎn); 每個(gè)觸點(diǎn)都由其位置,大小,形狀,壓力大小,和目標(biāo) element 描述。 TouchList 對(duì)象代表多個(gè)觸點(diǎn)的一個(gè)列表。具體包括以下屬性:
identifier 屬性: 表示touch實(shí)例的獨(dú)一無(wú)二的識(shí)別符。它在整個(gè)觸摸過(guò)程中保持不變(IE10+中使用 pointerId 屬性);
screenX/screenY 屬性: 分別表示觸摸點(diǎn)相對(duì)于屏幕左上角的橫坐標(biāo)和縱坐標(biāo),與頁(yè)面是否滾動(dòng)無(wú)關(guān);
clientX/clientY 屬性: 分別表示觸摸點(diǎn)相對(duì)于瀏覽器視口左上角的橫坐標(biāo)和縱坐標(biāo),與頁(yè)面是否滾動(dòng)無(wú)關(guān);
pageX/pageY 屬性: 分別表示觸摸點(diǎn)相對(duì)于當(dāng)前頁(yè)面左上角的橫坐標(biāo)和縱坐標(biāo),包含了頁(yè)面滾動(dòng)帶來(lái)的位移;
radiusX/radiusY 屬性: 分別返回觸摸點(diǎn)周?chē)艿接绊懙臋E圓范圍的X軸和Y軸,單位為像素;
rotationAngle 屬性: 表示觸摸區(qū)域的橢圓的旋轉(zhuǎn)角度,單位為度數(shù),在0到90度之間。指尖接觸屏幕,觸摸范圍會(huì)形成一個(gè)橢圓,這三個(gè)屬性就用來(lái)描述這個(gè)橢圓區(qū)域(IE10+中使用 rotation 屬性);
force 屬性: 返回一個(gè)0到1之間的數(shù)值,表示觸摸壓力。0代表沒(méi)有壓力,1代表硬件所能識(shí)別的最大壓力(IE10+中使用 pressure 屬性,取值0 - 255);
target 屬性: 返回一個(gè)Element節(jié)點(diǎn),代表觸摸發(fā)生的那個(gè)節(jié)點(diǎn)。當(dāng)這個(gè)觸點(diǎn)最開(kāi)始被跟蹤時(shí)(在 touchstart 事件中), 觸點(diǎn)位于的HTML元素.哪怕在觸點(diǎn)移動(dòng)過(guò)程中, 觸點(diǎn)的位置已經(jīng)離開(kāi)了這個(gè)元素的有效交互區(qū)域, 或者這個(gè)元素已經(jīng)被從文檔中移除. 需要注意的是, 如果這個(gè)元素在觸摸過(guò)程中被移除, 這個(gè)事件仍然會(huì)指向它, 但是不會(huì)再冒泡這個(gè)事件到 window 或 document 對(duì)象. 因此, 如果有元素在觸摸過(guò)程中可能被移除, 最佳實(shí)踐是將觸摸事件的監(jiān)聽(tīng)器綁定到這個(gè)元素本身, 防止元素被移除后, 無(wú)法再?gòu)乃纳弦患?jí)元素上偵測(cè)到從該元素冒泡的事件. 只讀屬性.
altKey/ctrlKey/metaKey/shiftKey 都為只讀屬性: 返回一個(gè)布爾值,表示觸摸的同時(shí),是否按下某個(gè)鍵
changedTouches 屬性: 返回一個(gè) TouchList 對(duì)象,包含了由當(dāng)前觸摸事件引發(fā)的所有Touch對(duì)象(即相關(guān)的觸摸點(diǎn))。它包含了代表所有從上一次觸摸事件到此次事件過(guò)程中,狀態(tài)發(fā)生了改變的觸點(diǎn)的 Touch 對(duì)象。只讀屬性。
targetTouches屬性: 返回一個(gè) TouchList 對(duì)象,包含了觸摸的目標(biāo) Element 節(jié)點(diǎn)內(nèi)部,所有仍然處于活動(dòng)狀態(tài)的觸摸點(diǎn)。
touches 屬性返回一個(gè) TouchList 對(duì)象(類(lèi)數(shù)組的對(duì)象),包含了所有當(dāng)前接觸觸摸平面的觸點(diǎn)的 Touch 對(duì)象,無(wú)論它們的起始于哪個(gè) element 上,也無(wú)論它們狀態(tài)是否發(fā)生了變化。只讀屬性
type 屬性: 指此次觸摸事件的類(lèi)型。
target屬性: 此次觸摸事件的目標(biāo) element 。這個(gè)目標(biāo)元素對(duì)應(yīng) TouchEvent.changedTouches 中的觸點(diǎn)的起始元素(在之后的事件類(lèi)型中有說(shuō)明),但是請(qǐng)注意: 此次事件中其他的觸點(diǎn)的起始元素可能有所不同。以防萬(wàn)一,應(yīng)使用和每一個(gè)多帶帶觸點(diǎn)相關(guān)聯(lián)的目標(biāo) 。
以下是 IE10+ 中的其他屬性:
hwTimestamp: 創(chuàng)建事件時(shí)間(毫秒);
isPrimary: 表示該時(shí)間是否是主事件;
pointerType: 取值自 event.MSPOINTER_TYPE_TOUCH, event.MAPOINTER_TYPE_PEN, event.MSPOINTER_TYPE_MOUSE, 表示觸摸設(shè)備;
tilt[X|Y]: 筆的傾斜程度;
舉一個(gè)簡(jiǎn)單例子:
function handleMove(evt) { evt.preventDefault(); // 阻止瀏覽器繼續(xù)處理觸摸事件,也阻止發(fā)出鼠標(biāo)事件 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); } }對(duì)于跨平臺(tái)交互,我封裝了一個(gè) tap相關(guān)事件如下:
//以下代碼并未兼容低版本 IE function addTapListener(node, callback){ var startEvent = window.onmousedown ? window.onmspointerdown ? "mspointerdow" : "mousedown" : "touchstart"; var event = window.onclick ? "click" : "touch"; var endEvent = window.onmouseup ? "mouseup" : "touchend"; node.addEventListener(startEvent, function(e){ var tap = document.createEvent("CustomEvent"); tap.initCustomEvent("tapstart", true, true, null); node.dispatchEvent(tap); }); node.addEventListener(event, function(e){ var tap = document.createEvent("CustomEvent"); tap.initCustomEvent("tap", true, true, null); node.dispatchEvent(tap); }); node.addEventListener(endEvent, function(e){ var tap = document.createEvent("CustomEvent"); tap.initCustomEvent("tapend", true, true, null); node.dispatchEvent(tap); }); node.addEventListener("tap", callback); }當(dāng)然本文僅僅列舉了一些常用事件,其實(shí)事件還有很多,本文會(huì)在必要的時(shí)候繼續(xù)更新,但即便如此也不可能窮盡所有的事件,比如還有動(dòng)畫(huà)事件: animationstart, animation, animationend 等等。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/97588.html
相關(guān)文章
瀏覽器常用事件解析
摘要:之前寫(xiě)過(guò)一篇瀏覽器事件的相關(guān)操作和事件運(yùn)行的原理瀏覽器事件解析。注意,頁(yè)面從瀏覽器緩存加載,并不會(huì)觸發(fā)事件。事件有一個(gè)屬性,返回一個(gè)布爾值。此外,不支持事件,可以使用事件代替。 之前寫(xiě)過(guò)一篇瀏覽器事件的相關(guān)操作和事件運(yùn)行的原理——JavaScript瀏覽器事件解析。這一篇主要寫(xiě)一些常用的事件及一些可能的坑。 表單事件 鍵盤(pán)事件 當(dāng) , 的值發(fā)生變化時(shí)觸發(fā)。此外,打開(kāi) contente...
vue常用知識(shí)點(diǎn)總結(jié)
摘要:這里借鑒了一下的處理方式,我們把單獨(dú)模塊的包裝成一個(gè)函數(shù),提供一個(gè)全局的回調(diào)方法,加載完成時(shí)候再調(diào)用回調(diào)函數(shù)。 感謝本文引用鏈接的各位大佬們,小菜鳥(niǎo)我只是個(gè)搬運(yùn)工 1.談一談你理解的vue是什么樣子的? vue是數(shù)據(jù)、視圖分離的一個(gè)框架,讓數(shù)據(jù)與視圖間不會(huì)發(fā)生直接聯(lián)系。MVVM 組件化:把整體拆分為各個(gè)可以復(fù)用的個(gè)體 數(shù)據(jù)驅(qū)動(dòng):通過(guò)數(shù)據(jù)變化直接影響bom展示,避免dom操作。 可以在...
發(fā)表評(píng)論
0條評(píng)論
閱讀 3075·2021-11-23 09:51
閱讀 2920·2021-11-11 16:55
閱讀 3020·2021-10-14 09:43
閱讀 1463·2021-09-23 11:22
閱讀 1102·2019-08-30 11:04
閱讀 1787·2019-08-29 11:10
閱讀 1023·2019-08-27 10:56
閱讀 3213·2019-08-26 12:01