<div onclick="alert(1);"></div>
window.onload=function(){}
target.addEventListener(type, listener[, useCapture]);
type:事件名稱(事件類型),字符串,大小寫不敏感。
listener:監(jiān)聽函數(shù)。事件發(fā)生時,會調(diào)用該監(jiān)聽函數(shù)。
useCapture:布爾值,表示監(jiān)聽函數(shù)是否在捕獲階段(capture)觸發(fā),默認(rèn)為false(監(jiān)聽函數(shù)只在冒泡階段被觸發(fā))。老式瀏覽器規(guī)定該參數(shù)必寫,較新版本的瀏覽器允許該參數(shù)可選。為了保持兼容,建議總是寫上該參數(shù)。
addEventListener('click',listener,false);
<button id="mybutton">點擊</button>
var v = document.getElementById('mybutton');
v.onclick = function() {alert('1');}
v.addEventListener('click',function(){alert('2');},false);
target.dispatchEvent(event)
//添加事件處理器
var addEvent = function(element, type, handler, useCapture) {
if(element.addEventListener) {
element.addEventListener(type, handler, useCapture ? true : false);
} else if(element.attachEvent) {
element.attachEvent('on' + type, handler);
} else if(element != window){
element['on' + type] = handler;
}
};
//移除某個事件處理器
var removeEvent = function(element, type, handler, useCapture) {
if(element.removeEventListener) {
element.removeEventListener(type, handler, useCapture ? true : false); } else if(element.detachEvent) {
element.detachEvent('on' + type, handler);
} else if(element != window){
element['on' + type] = null;
}
};
function handler(event){
event = event || window.event;
}
e.onclick=function(){}
10.2.3 事件處理程序的作用域
事件處理程序在其定義的作用域而非調(diào)用時的作用域中執(zhí)行,并且它們能存取那個作用域中的任何一個本地變量。
10.2.4 事件處理程序的返回值
通過設(shè)置對象屬性或HTML屬性注冊事件處理程序的返回值有時是非常有意義的。通常情況下,返回值false就是告訴瀏覽器不要執(zhí)行這個事件相關(guān)的默認(rèn)操作。比如,表單提交按鈕的onclick事件處理程序能返回false阻止瀏覽器提交表單。
v.onclick = function() {
return false;
}
理解事件處理程序的返回值只對通過屬性注冊的處理程序才有意義。
10.2.5 調(diào)用順序
文檔元素或其他對象可以指定事件類型注冊多個事件處理程序。當(dāng)適當(dāng)?shù)氖录l(fā)生時,瀏覽器必須按照下面的規(guī)則調(diào)用所有的事件處理程序:
10.2.6 事件傳播
當(dāng)事件目標(biāo)是Window對象或其他一些單獨(dú)對象(比如XMLHttpRequest)時,瀏覽器會簡單的通過調(diào)用對象上適當(dāng)?shù)奶幚沓绦蝽憫?yīng)事件。
在調(diào)用在目標(biāo)元素上注冊的事件處理函數(shù)后,大部分事件會“冒泡”到DOM樹根。
發(fā)生在文檔元素上的大部分事件都會冒泡,但有些例外,比如focus、blur和scroll事件。文檔元素上的load事件會冒泡,但它會在Document對象上停止冒泡而不會傳播到Window對象。只有當(dāng)整個文檔都加載完畢時才會觸發(fā)window對象的load事件。
當(dāng)事件目標(biāo)是文檔或文檔元素時,它會在不同的DOM節(jié)點之間傳播(propagation)。
分為三個階段:
事件代理(事件委托)
基于事件會在冒泡階段向上傳播到父節(jié)點,我們可以將子節(jié)點的監(jiān)聽事件定義在父節(jié)點上,由父節(jié)點的監(jiān)聽函數(shù)統(tǒng)一處理多個子元素的事件。這種方法叫做事件的代理(delegation)。
<div id="div">
<div id="item">123</div>
</div>
document.getElementById('div').addEventListener('click', function(e) {
var target = e.target;
if(target.getAttribute('id').toLowerCase() == 'item') {
alert(1);
}
});
如果使用事件代理,以后插入的新節(jié)點仍然可以監(jiān)聽的到。
如果使用JQuery,我們要為新增節(jié)點添加事件,除了在新增事件后添加事件外,還可以用下面的代碼:
$(document).on('click','div',function(){})
這種方式其實就是使用了事件代理。
10.2.7 事件取消
用屬性注冊的世界處理程序的返回值能用于取消事件的瀏覽器默認(rèn)操作。在支持addEventListener()的瀏覽器中,也能通過調(diào)用事件對象的preventDefault()方法取消事件的默認(rèn)操作。
在IE9之前的IE中,可以通過設(shè)置事件對象的returnValue屬性為false來達(dá)到同樣的效果。
function cancelHandler(event){
var event = event || window.event;
if(event.preventDefault) {event.preventDefault();} //標(biāo)準(zhǔn)
if(event.returnValue) { event.returnValue = false;} // IE
return false; //用于處理使用對象屬性注冊的處理程序
}
Event對象提供了一個屬性defaultPrevented,返回一個布爾值,默認(rèn)false,表示該事件是否調(diào)用過preventDefault方法。
取消事件傳播
在支持addEventListener()的瀏覽器中,可以調(diào)用事件對象的一個stopPropagation()方法以阻止事件的繼續(xù)傳播。
e.stopPropagation()
//IE
e.cancelBubble = true;
在Event對象上還有一個方法stopImmediatePropagation(),阻止同一個事件的其他監(jiān)聽函數(shù)被調(diào)用。也就是說,如果同一個節(jié)點對于同一個事件指定了多個監(jiān)聽函數(shù),這些函數(shù)會根據(jù)添加的順序依次調(diào)用。只要其中有一個監(jiān)聽函數(shù)調(diào)用了stopImmediatePropagation方法,其他的監(jiān)聽函數(shù)就不會再執(zhí)行了。
e.addEventListener('click',function(event){
event.stopImmediatePropagation();
});
e.addEventListener('click',function(event){
//不會觸發(fā)
});
10.3 文檔事件
(1)beforeunload事件、unload事件、load事件、error事件、pageshow事件、pagehide事件
beforeunload
當(dāng)瀏覽器將要跳轉(zhuǎn)到新頁面時觸發(fā)這個事件。如果事件處理程序返回一個字符串,那么它將出現(xiàn)在詢問用戶是否想離開當(dāng)前頁面的標(biāo)準(zhǔn)對話框中。
window.addEventListener('beforeunload',function(e){
var message = '你確認(rèn)要離開嗎!';
e.returnValue = message;
return message
});
unload
unload事件在窗口關(guān)閉或者document對象將要卸載時觸發(fā),發(fā)生在window、body、frameset等對象上面。它的觸發(fā)順序排在beforeunload、pagehide事件后面。unload事件只在頁面沒有被瀏覽器緩存時才會觸發(fā),換言之,如果通過按下“前進(jìn)/后退”導(dǎo)致頁面卸載,并不會觸發(fā)unload事件。
load、error
load事件直到文檔和所有圖片加載完畢時才會觸發(fā),error事件在頁面加載失敗時觸發(fā)。注意,頁面從瀏覽器緩存加載,并不會觸發(fā)load事件。
pageshow、pagehide
默認(rèn)情況下,瀏覽器會在當(dāng)前會話(session)緩存頁面,當(dāng)用戶點擊“前進(jìn)/后退”按鈕時,瀏覽器就會從緩存中加載頁面。
pageshow事件在頁面加載時觸發(fā),包括第一次加載和從緩存加載兩種情況。如果要指定頁面每次加載(不管是不是從瀏覽器緩存)時都運(yùn)行的代碼,可以放在這個事件的監(jiān)聽函數(shù)。
pageshow事件有一個persisted屬性,返回一個布爾值。頁面第一次加載時,這個屬性是false;當(dāng)頁面從緩存加載時,這個屬性是true。
pagehide事件與pageshow事件類似,當(dāng)用戶通過“前進(jìn)/后退”按鈕,離開當(dāng)前頁面時觸發(fā)。
pagehide事件的event對象有一個persisted屬性,將這個屬性設(shè)為true,就表示頁面要保存在緩存中;設(shè)為false,表示網(wǎng)頁不保存在緩存中,這時如果設(shè)置了unload事件的監(jiān)聽函數(shù),該函數(shù)將在pagehide事件后立即運(yùn)行。
(2)DOMContentLoaded事件、readystatechange事件
DOMContentLoaded事件:當(dāng)文檔加載解析完畢且所有延遲(deferred)腳本(圖片未加載完畢)都執(zhí)行完畢時會觸發(fā),此時圖片和異步(async)腳本可能依舊在加載,但是文檔已經(jīng)為操作準(zhǔn)備就緒了。也就是說,這個事件,發(fā)生在load事件之前。
document.addEventListener('DOMContentLoaded',handler,false);
readystatechange事件:document.readyState屬性會隨著文檔加載過程而變,而每次狀態(tài)改變,Document對象上的readystatechange事件都會觸發(fā)。
document.onreadystatechange = function() {
if(document.readyState == 'complete'){
}
}
(3)scroll事件、resize事件
scroll事件在文檔或文檔元素滾動時觸發(fā),主要出現(xiàn)在用戶拖動滾動條。
resize事件在改變?yōu)g覽器窗口大小時觸發(fā),發(fā)生在window、body、frameset對象上面。
(4)hashchange事件、popstate事件
hashchange事件在URL的hash部分(即#號后面的部分,包括#號)發(fā)生變化時觸發(fā)。如果老式瀏覽器不支持該屬性,可以通過定期檢查location.hash屬性,模擬該事件。
popstate事件在瀏覽器的history對象的當(dāng)前記錄發(fā)生顯式切換時觸發(fā)。注意,調(diào)用history.pushState()或history.replaceState(),并不會觸發(fā)popstate事件。該事件只在用戶在history記錄之間顯式切換時觸發(fā),比如鼠標(biāo)點擊“后退/前進(jìn)”按鈕,或者在腳本中調(diào)用history.back()、history.forward()、history.go()時觸發(fā)。
(5)cut事件、copy事件、paste事件
這三個事件屬于文本操作觸發(fā)的事件。
cut事件:在將選中的內(nèi)容從文檔中移除,加入剪貼板后觸發(fā)。
copy事件:在選中的內(nèi)容加入剪貼板后觸發(fā)。
paste事件:在剪貼板內(nèi)容被粘貼到文檔后觸發(fā)。
這三個事件都有一個clipboardData只讀屬性。該屬性存放剪貼的數(shù)據(jù),是一個DataTransfer對象。
(6)焦點事件
焦點事件發(fā)生在Element節(jié)點和document對象上。
focus事件:Element節(jié)點獲得焦點后觸發(fā),該事件不會冒泡。
blur事件:Element節(jié)點失去焦點后觸發(fā),該事件不會冒泡。
focusin事件:Element節(jié)點將要獲得焦點時觸發(fā),發(fā)生在focus事件之前。該事件會冒泡。Firefox不支持該事件。
focusout事件:Element節(jié)點將要失去焦點時觸發(fā),發(fā)生在blur事件之前。該事件會冒泡。Firefox不支持該事件。
這四個事件的事件對象,帶有target屬性(返回事件的目標(biāo)節(jié)點)和relatedTarget屬性(返回一個Element節(jié)點)。對于focusin事件,relatedTarget屬性表示失去焦點的節(jié)點;對于focusout事件,表示將要接受焦點的節(jié)點;對于focus和blur事件,該屬性返回null。
由于focus和blur事件不會冒泡,只能在捕獲階段觸發(fā),所以addEventListener方法的第三個參數(shù)需要設(shè)為true。
10.4 鼠標(biāo)事件
(1)click
click事件當(dāng)用戶在Element節(jié)點、document節(jié)點、window對象上,單擊鼠標(biāo)(或者按下回車鍵)時觸發(fā)。
“鼠標(biāo)單擊”定義為,用戶在同一個位置完成一次mousedown動作和mouseup動作。它們的觸發(fā)順序是:mousedown首先觸發(fā),mouseup接著觸發(fā),click最后觸發(fā)。
(2)contextmenu
contextmenu事件在一個節(jié)點上點擊鼠標(biāo)右鍵時觸發(fā),或者按下“上下文菜單”鍵時觸發(fā)。
可以通過下面的方式阻止“上下文菜單”的出現(xiàn):
document.oncontextmenu=function(){
return false;
}
(3)dblclick
dblclick事件當(dāng)用戶在element、document、window對象上,雙擊鼠標(biāo)時觸發(fā)。該事件會在mousedown、mouseup、click之后觸發(fā)。
(4)mousedown、mouseup
mouseup事件在釋放按下的鼠標(biāo)鍵時觸發(fā)。
mousedown事件在按下鼠標(biāo)鍵時觸發(fā)。
(5)mousemove
mousemove事件當(dāng)鼠標(biāo)在一個節(jié)點內(nèi)部移動時觸發(fā)。當(dāng)鼠標(biāo)持續(xù)移動時,該事件會連續(xù)觸發(fā)。為了避免性能問題,建議對該事件的監(jiān)聽函數(shù)做一些限定,比如限定一段時間內(nèi)只能運(yùn)行一次代碼。
(6)mouseover、mouseenter
mouseover事件和mouseenter事件,都是鼠標(biāo)進(jìn)入一個節(jié)點時觸發(fā)。
兩者的區(qū)別是,mouseenter事件只觸發(fā)一次,而只要鼠標(biāo)在節(jié)點內(nèi)部移動,mouseover事件會在子節(jié)點上觸發(fā)多次。
(7)mouseout、mouseleave
mouseout事件和mouseleave事件,都是鼠標(biāo)離開一個節(jié)點時觸發(fā)。
除了“mouseenter”和“mouseleave”外的所有鼠標(biāo)事件都能冒泡。鏈接和提交按鈕上的click事件都有默認(rèn)操作且能夠阻止??梢匀∠舷挛牟藛问录碜柚癸@示上下文菜單。
傳遞給鼠標(biāo)事件處理程序的事件對象有clientX和clientY屬性,它們指定了鼠標(biāo)指針相對于包含窗口的坐標(biāo)。加入窗口的滾動偏移量可以把鼠標(biāo)位置轉(zhuǎn)換成文檔坐標(biāo)。
MouseEvent對象的屬性
(1)button、buttons
button屬性指定當(dāng)事件發(fā)生時哪個鼠標(biāo)按鍵按下。
-1:沒有按下鍵。
0:按下主鍵(通常是左鍵)。
1:按下輔助鍵(通常是中鍵或者滾輪鍵)。
2:按下次鍵(通常是右鍵)。
buttons屬性返回一個3個比特位的值,表示同時按下了哪些鍵。它用來處理同時按下多個鼠標(biāo)鍵的情況。
1:二進(jìn)制為001,表示按下左鍵。
2:二進(jìn)制為010,表示按下右鍵。
4:二進(jìn)制為100,表示按下中鍵或滾輪鍵。
同時按下多個鍵的時候,每個按下的鍵對應(yīng)的比特位都會有值。比如,同時按下左鍵和右鍵,會返回3(二進(jìn)制為011)。
(2)clientX,clientY
clientX屬性返回鼠標(biāo)位置相對于瀏覽器窗口左上角的水平坐標(biāo),單位為像素,與頁面是否橫向滾動無關(guān)。
clientY屬性返回鼠標(biāo)位置相對于瀏覽器窗口左上角的垂直坐標(biāo),單位為像素,與頁面是否縱向滾動無關(guān)。
(3)movementX,movementY
movementX屬性返回一個水平位移,單位為像素,表示當(dāng)前位置與上一個mousemove事件之間的水平距離。在數(shù)值上,等于currentEvent.movementX = currentEvent.screenX - previousEvent.screenX。
movementY屬性返回一個垂直位移,單位為像素,表示當(dāng)前位置與上一個mousemove事件之間的垂直距離。在數(shù)值上,等于currentEvent.movementY = currentEvent.screenY - previousEvent.screenY。
(4)screenX,screenY
screenX屬性返回鼠標(biāo)位置相對于屏幕左上角的水平坐標(biāo),單位為像素。
screenY屬性返回鼠標(biāo)位置相對于屏幕左上角的垂直坐標(biāo),單位為像素。
(7)pageX、pageY
pageX和pageY分別是觸點相對HTML文檔左邊沿的X坐標(biāo)和觸點相對HTML文檔上邊沿的Y坐標(biāo)。只讀屬性。
當(dāng)存在滾動的偏移時,pageX包含了水平滾動的偏移,pageY包含了垂直滾動的偏移。
(6)relatedTarget
relatedTarget屬性返回事件的次要相關(guān)節(jié)點。對于那些沒有次要相關(guān)節(jié)點的事件,該屬性返回null。
10.5 鼠標(biāo)滾輪事件
所有的現(xiàn)代瀏覽器都支持鼠標(biāo)滾輪,并在用戶滾動滾輪時觸發(fā)事件。瀏覽器通常使用鼠標(biāo)滾輪滾動或縮放文檔,但可以通過取消mousewheel事件來阻止這些默認(rèn)操作。
所有瀏覽器都支持“mousewheel”事件,但Firefox使用“DOMMouseScroll”事件。
傳遞給“mousewheel”處理程序的事件對象有wheelDelta屬性,其指定用戶滾動滾輪有多遠(yuǎn)(根據(jù)這個判斷滾動方向)。
遠(yuǎn)離用戶方向的一次鼠標(biāo)滾輪“單擊”的wheelDelta值通常是120,而接近用戶方向的一次“單擊”的值是-120。返回的總是120的倍數(shù)(120表明mouse向上滾動,-120表明鼠標(biāo)向下滾動)
在Safari和Chrome中,為了支持使用二維軌跡球而非一維滾輪的Apple鼠標(biāo),除了wheelDelta屬性外,事件對象還有wheelDeltaX和wheelDeltaY,而wheelDelta和wheelDeltaY的值一直相同。
而在Firefox中,傳遞給“DOMMouseScroll”的屬性是detail。不過, detail屬性值的縮放比率和正負(fù)符號不同wheelDelta,detail值乘以-40和wheelDelta值相等。記錄其滾動距離的是“detail”屬性,它返回的是3的倍數(shù)(3表明mouse向下滾動,-3表明mouse向上滾動)。
window.onmousewheel = document.onmousewheel = scrollWheel;
function scrollWheel(e){
e = e || window.event;
if(e.wheelDelta) { //判斷瀏覽器IE,谷歌滑輪事件
if(e.wheelDelta > 0) {
//當(dāng)滑輪向上滾動時
} else if(e.wheelDelta < 0) {
//當(dāng)滑輪向下滾動時
};
} else if(e.detail) { //Firefox滑輪事件
if(e.detail < 0) {
//當(dāng)滑輪向上滾動時
} else if(e.detail > 0) {
//當(dāng)滑輪向下滾動時
};
};
}
10.6 鍵盤事件
鍵盤事件用來描述鍵盤行為,主要有keydown、keypress、keyup三個事件。
keydown:按下鍵盤時觸發(fā)該事件。
keypress:只要按下的鍵并非Ctrl、Alt、Shift和Meta,就接著觸發(fā)keypress事件。
keyup:松開鍵盤時觸發(fā)該事件。
textinput
任何時候,只要用戶輸入文本都會觸發(fā)。在Webkit瀏覽器中支持“textInput”事件。
事件對象屬性data(保存輸入文本),inputMethod屬性(用于指定輸入源)
注意:keypress和textinput事件是在新輸入的文本真正插入到聚焦的文檔元素前觸發(fā)的。
如果用戶一直按鍵不松開,就會重復(fù)觸發(fā)keydown、keypress,直到用戶松開才會觸發(fā)keyup。
屬性
keycode
指定了輸入字符的編碼。在Firefox中使用的是charCode屬性。
altKey,ctrlKey,metaKey,shiftKey
altKey、ctrlKey、metaKey和shiftKey屬性指定了當(dāng)事件發(fā)生時是否有各種鍵盤輔助鍵按下。
altKey屬性:alt鍵
ctrlKey屬性:key鍵
metaKey屬性:Meta鍵(Mac鍵盤是一個四瓣的小花,Windows鍵盤是Windows鍵)
shiftKey屬性:Shift鍵
key,charCode key屬性返回一個字符串,表示按下的鍵名。如果同時按下一個控制鍵和一個符號鍵,則返回符號鍵的鍵名。比如,按下Ctrl+a,則返回a。如果無法識別鍵名,則返回字符串Unidentified。
主要功能鍵的鍵名(不同的瀏覽器可能有差異):Backspace,Tab,Enter,Shift,Control,Alt,CapsLock,CapsLock,Esc,Spacebar,PageUp,PageDown,End,Home,Left,Right,Up,Down,PrintScreen,Insert,Del,Win,F(xiàn)1~F12,NumLock,Scroll等。
charCode屬性返回一個數(shù)值,表示keypress事件按鍵的Unicode值,keydown和keyup事件不提供這個屬性。注意,該屬性已經(jīng)從標(biāo)準(zhǔn)移除,雖然瀏覽器還支持,但應(yīng)該盡量不使用。
String.fromCharCode()
一個keypress事件表示輸入的單個字符。事件對象以數(shù)字Unicode編碼的形式指定字符,所以必須用String.fromChatCode()把它轉(zhuǎn)換成字符串。
10.7 表單事件
(1)input、propertychange
檢測文本輸入元素的value屬性改變,這兩個事件是在新輸入的文本真正插入到聚焦的文檔元素前觸發(fā)的。
一般用在<inupt>和<textarea>里,不過,當(dāng)將contenteditable屬性設(shè)置為true時,只要值變化,也會觸發(fā)這兩個事件。
(2)change
當(dāng)<input>、<select>和<textarea>的值發(fā)生變化時都會觸發(fā)change事件。只有全部修改完成時它才會觸發(fā),這也是它和input事件的區(qū)別。
具體分下面幾種情況:
激活單選框(radio)或復(fù)選框(checkbox)時觸發(fā)。
用戶提交時觸發(fā)。比如,從下列列表(select)完成選擇,在日期或文件輸入框完成選擇。
當(dāng)文本框或textarea元素的值發(fā)生改變,并且喪失焦點時觸發(fā)。
(3)select
當(dāng)<input>和<textarea>中選中文本時觸發(fā)select事件。
(4)reset、submit
這兩個事件是發(fā)生在表單對象上,而不是發(fā)生在表單的成員上。
reset事件:當(dāng)表單重置(所有表單成員的值變回默認(rèn)值)時觸發(fā)。
submit事件:當(dāng)表單數(shù)據(jù)向服務(wù)器提交時觸發(fā)。
注意:submit事件的發(fā)生對象是form元素,而不是button元素(即使它的類型是submit),因為提交的是表單,而不是按鈕。
10.8 觸控事件
觸控事件提供了響應(yīng)用戶對觸摸屏或觸摸板上操作的能力。
觸控API提供了下面三個接口
TouchEvent:代表當(dāng)觸摸行為在平面上發(fā)生變化時發(fā)生的事件
Touch:代表用戶與觸摸屏幕間的一個接觸點
TouchList:代表一系列的Touch;一般在用戶多個手指同時解除屏幕時使用
10.8.1 TouchEvent
TouchEvent是一類描述手指在觸摸平面的狀態(tài)變化的事件。
(1)觸摸事件的類型
touchstart:用戶接觸觸摸屏?xí)r觸發(fā),它的target屬性返回發(fā)生觸摸的Element節(jié)點。
touchend:用戶不再接觸觸摸屏?xí)r(或者移出屏幕邊緣時)觸發(fā),它的target屬性與touchstart事件的target屬性是一致的,它的changedTouches屬性返回一個TouchList對象,包含所有不再觸摸的觸摸點(Touch對象)。
touchmove:用戶移動觸摸點時觸發(fā),它的target屬性與touchstart事件的target屬性一致。如果觸摸的半徑、角度、力度發(fā)生變化,也會觸發(fā)該事件。
touchcancel:觸摸點取消時觸發(fā),比如在觸摸區(qū)域跳出一個彈出框窗口(modal window)、觸摸點離開了文檔區(qū)域(進(jìn)入瀏覽器菜單欄區(qū)域)、用戶放置更多的觸摸點(自動取消早先的觸摸點)。
touchenter:當(dāng)觸點進(jìn)去某個elemen時觸發(fā)。沒有冒泡過程。
touchleave:當(dāng)觸點離開某個element時觸發(fā)。沒有冒泡過程。
(2)TouchEvent的屬性
鍵盤屬性
以下屬性都為只讀屬性,返回一個布爾值,表示觸摸的同時,是否按下某個鍵。
altKey 是否按下alt鍵
ctrlKey 是否按下ctrl鍵
metaKey 是否按下meta鍵
shiftKey 是否按下shift鍵
changedTouches
返回一個TouchList對象,包含了代表所有從上一次觸摸事件到此次事件過程中,狀態(tài)發(fā)生了改變的觸點的Touch對象。只讀屬性。
targetTouches
返回一個TouchList對象,包含了所有當(dāng)前接觸觸摸平面的觸點的Touch對象(也可以說是處于活動狀態(tài)的觸點的Touch對象)。只讀屬性。
touches
返回一個TouchList對象,包含了所有當(dāng)前接觸觸摸平面的觸點的Touch對象。只讀屬性。
type
此次觸摸事件的類型。
target
此次觸摸事件的目標(biāo)元素(element)。這個目標(biāo)元素對應(yīng) TouchEvent.changedTouches 中的觸點的起始元素。
10.8.2 Touch
Touch對象表示在觸控設(shè)備上的觸控點。通常是指手指或觸控筆在觸屏設(shè)備上的操作。
每個Touch對象代表一個觸點,每個觸點由其位置、大小、形狀、壓力大小和目標(biāo)element描述。
(1)Touch屬性
以下屬性描述了用戶的觸摸行為
identifier
此Touch對象的唯一標(biāo)識符。一次觸摸動作在平面上移動的整個過程中,該標(biāo)識符不變,可以根據(jù)它來判斷跟蹤是否在同一次觸摸過程。只讀屬性。
screenX、screenY
screenX和screenY分別是觸點相對屏幕左邊沿的X坐標(biāo)和觸點相對屏幕上邊沿的Y坐標(biāo)。只讀屬性。
clientX、clientY
clientX和clientY分別是觸點相對于可視區(qū)左邊沿的X坐標(biāo)和觸點相對可視區(qū)上邊沿的Y坐標(biāo)。兩個屬性都不包括任何滾動偏移。只讀屬性。
pageX、pageY
pageX和pageY分別是觸點相對HTML文檔左邊沿的X坐標(biāo)和觸點相對HTML文檔上邊沿的Y坐標(biāo)。只讀屬性。
當(dāng)存在滾動的偏移時,pageX包含了水平滾動的偏移,pageY包含了垂直滾動的偏移。
radiusX、radiusY、rotationAngle
radiusX:能夠包圍用戶和觸摸平面的接觸面的最小橢圓的水平軸(X軸)半徑. 這個值的單位和 screenX 相同。只讀屬性。
radiusY:能夠包圍用戶和觸摸平面的接觸面的最小橢圓的垂直軸(Y軸)半徑. 這個值的單位和 screenY 相同。只讀屬性。
rotationAngle:由radiusX 和 radiusY 描述的正方向的橢圓,需要通過順時針旋轉(zhuǎn)這個角度值,才能最精確地覆蓋住用戶和觸摸平面的接觸面,單位為度數(shù),在0到90度之間。只讀屬性。
force
手指擠壓觸摸平面的壓力大小, 從0.0(沒有壓力)到1.0(最大壓力)的浮點數(shù). 只讀屬性.
target
當(dāng)這個觸點最開始被跟蹤時(在 touchstart 事件中), 觸點位于的HTML元素。也就是觸摸發(fā)生時的那個節(jié)點。
10.8.3 TouchList
一個TouchList代表一個觸摸平面上所有觸點的列表。比如一個用戶用三根手指接觸平面,與之相關(guān)的TouchList對于每根手指都會生成一個Touch對象,共計三個。
(1)TouchList的屬性
length
返回TouchList中Touch對象的數(shù)量,只讀屬性。
(2)方法
identifiedTouch()
返回列表中標(biāo)識符與指定值匹配的第一個Touch對象。
item()
返回列表中以指定索引值的Touch對象。也可以使用數(shù)組的語法:touchlist[index]
10.8.4 其他觸控事件
gesturestart、gestureend
scale、rotation
10.9 進(jìn)度事件
進(jìn)度事件用來描述一個事件進(jìn)展的過程。比如XMLHttpRequest對象發(fā)出的HTTP請求的過程、<img>、<audio>、<video>、<style>、<link>加載外部資源的過程。下載和上傳都會發(fā)生進(jìn)度事件。
進(jìn)度事件有以下幾種:
abort事件:當(dāng)進(jìn)度事件被中止時觸發(fā)。如果發(fā)生錯誤,導(dǎo)致進(jìn)程中止,不會觸發(fā)該事件。
error事件:由于錯誤導(dǎo)致資源無法加載時觸發(fā)。
load事件:進(jìn)度成功結(jié)束時觸發(fā)。
loadstart事件:進(jìn)度開始時觸發(fā)。
loadend事件:進(jìn)度停止時觸發(fā),發(fā)生順序排在error事件\abort事件\load事件后面。
progress事件:當(dāng)操作處于進(jìn)度之中,由傳輸?shù)臄?shù)據(jù)塊不斷觸發(fā)。
timeout事件:進(jìn)度超過限時觸發(fā)。
10.11 拖放事件
拖放(Drag-and-Drop,DnD)是在“拖放源(drag source)”和“拖放目標(biāo)(drop target)”之間傳輸數(shù)據(jù)的用戶界面。
拖拉的對象有好幾種,包括Element節(jié)點、圖片、鏈接、選中的文字等等。在HTML網(wǎng)頁中,除了Element節(jié)點默認(rèn)不可以拖拉,其他(圖片、鏈接、選中的文字)都是可以直接拖拉的。為了讓Element節(jié)點可拖拉,可以將該節(jié)點的draggable屬性設(shè)為true。
<div draggable="true"> 此區(qū)域可拖拉 </div>
draggable屬性可用于任何Element節(jié)點,但是圖片(img元素)和鏈接(a元素)不加這個屬性,就可以拖拉。對于它們,用到這個屬性的時候,往往是將其設(shè)為false,防止拖拉。
注意:一旦某個Element節(jié)點的draggable屬性設(shè)為true,就無法再用鼠標(biāo)選中該節(jié)點內(nèi)部的文字或子節(jié)點了。
10.11.1 拖放事件:
dragstart:當(dāng)一個元素開始被拖拽的時候觸發(fā)。用戶拖拽的元素需要附加dragstart事件。在這個事件中,監(jiān)聽器將設(shè)置與這次拖拽相關(guān)的信息,例如拖動的數(shù)據(jù)和圖像。
dragenter:當(dāng)拖拽中的鼠標(biāo)第一次進(jìn)入一個元素的時候觸發(fā)。這個事件的監(jiān)聽器需要指明是否允許在這個區(qū)域釋放鼠標(biāo)。如果沒有設(shè)置監(jiān)聽器,或者監(jiān)聽器沒有進(jìn)行操作,則默認(rèn)不允許釋放。當(dāng)你想要通過類似高亮或插入標(biāo)記等方式來告知用戶此處可以釋放,你將需要監(jiān)聽這個事件。
dragover:當(dāng)拖拽中的鼠標(biāo)移動經(jīng)過一個元素的時候觸發(fā)。大多數(shù)時候,監(jiān)聽過程發(fā)生的操作與dragenter事件是一樣的。
dragleave:當(dāng)拖拽中的鼠標(biāo)離開元素時觸發(fā)。監(jiān)聽器需要將作為可釋放反饋的高亮或插入標(biāo)記去除。
drag:這個事件在拖拽源觸發(fā)。即在拖拽操作中觸發(fā)dragstart事件的元素。
drop:這個事件在拖拽操作結(jié)束釋放時于釋放元素上觸發(fā)。一個監(jiān)聽器用來響應(yīng)接收被拖拽的數(shù)據(jù)并插入到釋放之地。這個事件只有在需要時才觸發(fā)。當(dāng)用戶取消了拖拽操作時將不觸發(fā),例如按下了Escape(ESC)按鍵,或鼠標(biāo)在非可釋放目標(biāo)上釋放了按鍵。
dragend:拖拽源在拖拽操作結(jié)束將得到dragend事件對象,不管操作成功與否。
注意點:
<div ondragover="return false">
<div ondragover="event.preventDefault()">
下面是一個例子,將圖片拖放到另一個div中:
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<img id="drag1" src="f.jpg" draggable="true" ondragstart="drag(event)" >
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
10.11.2 DataTransfer對象
所有的拖拉事件都有一個dataTransfer屬性,用來保存需要傳遞的數(shù)據(jù)。返回一個DataTransfer對象。
拖拉的數(shù)據(jù)保存兩方面的數(shù)據(jù):數(shù)據(jù)的種類(又稱格式)和數(shù)據(jù)的值。數(shù)據(jù)的種類是一個MIME字符串,比如 text/plain或者image/jpeg,數(shù)據(jù)的值是一個字符串。一般來說,如果拖拉一段文本,則數(shù)據(jù)默認(rèn)就是那段文本;如果拖拉一個鏈接,則數(shù)據(jù)默認(rèn)就是鏈接的URL。
當(dāng)拖拉事件開始的時候,可以提供數(shù)據(jù)類型和數(shù)據(jù)值;在拖拉過程中,通過dragenter和dragover事件的監(jiān)聽函數(shù),檢查數(shù)據(jù)類型,以確定是否允許放下(drop)被拖拉的對象。比如,在只允許放下鏈接的區(qū)域,檢查拖拉的數(shù)據(jù)類型是否為text/uri-list。
發(fā)生drop事件時,監(jiān)聽函數(shù)取出拖拉的數(shù)據(jù),對其進(jìn)行處理。
(1)DataTransfer對象的屬性
dropEffect
dropEffect屬性設(shè)置放下(drop)被拖拉節(jié)點時的效果,可能的值包括copy(復(fù)制被拖拉的節(jié)點)、move(移動被拖拉的節(jié)點)、link(創(chuàng)建指向被拖拉的節(jié)點的鏈接)、none(無法放下被拖拉的節(jié)點)。設(shè)置除此以外的值,都是無效的。
e.dataTransfer.dropEffect = 'copy';
dropEffect屬性一般在dragenter和dragover事件的監(jiān)聽函數(shù)中設(shè)置,對于dragstart、drag、dragleave這三個事件,該屬性不起作用。
effectAllowed
effectAllowed屬性設(shè)置本次拖拉中允許的效果,可能的值包括copy(復(fù)制被拖拉的節(jié)點)、move(移動被拖拉的節(jié)點)、link(創(chuàng)建指向被拖拉節(jié)點的鏈接)、copyLink(允許copy或link)、copyMove(允許copy或move)、linkMove(允許link或move)、all(允許所有效果)、none(無法放下被拖拉的節(jié)點)、uninitialized(默認(rèn)值,等同于all)。如果某種效果是不允許的,用戶就無法在目標(biāo)節(jié)點中達(dá)成這種效果。
dragstart事件的監(jiān)聽函數(shù),可以設(shè)置被拖拉節(jié)點允許的效果;dragenter和dragover事件的監(jiān)聽函數(shù),可以設(shè)置目標(biāo)節(jié)點允許的效果。
e.dataTransfer.effectAllowed = 'copy';
files
files屬性是一個FileList對象,包含一組本地文件,可以用來在拖拉操作中傳送。如果本次拖拉不涉及文件,則屬性為空的FileList對象。
types
types屬性是一個數(shù)組,保存每一次拖拉的數(shù)據(jù)格式,比如拖拉文件,則格式信息就為File。
(2)DataTransfer對象的方法
setData()
setData方法用來設(shè)置事件所帶有的指定類型的數(shù)據(jù)。它接受兩個參數(shù),第一個是數(shù)據(jù)類型,第二個是具體數(shù)據(jù)。如果指定的類型在現(xiàn)有數(shù)據(jù)中不存在,則該類型將寫入types屬性;如果已經(jīng)存在,在該類型的現(xiàn)有數(shù)據(jù)將被替換。
e.dataTransfer.setData('text/plain','bb');
getData()
getData方法接受一個字符串(表示數(shù)據(jù)類型)作為參數(shù),返回事件所帶的指定類型的數(shù)據(jù)(通常是用setData方法添加的數(shù)據(jù))。如果指定類型的數(shù)據(jù)不存在,則返回空字符串。通常只有drop事件觸發(fā)后,才能取出數(shù)據(jù)。如果取出另一個域名存放的數(shù)據(jù),將會報錯。
clearData()
clearData方法接受一個字符串(表示數(shù)據(jù)類型)作為參數(shù),刪除事件所帶的指定類型的數(shù)據(jù)。如果沒有指定類型,則刪除所有數(shù)據(jù)。如果指定類型不存在,則原數(shù)據(jù)不受影響。
e.dataTransfer.clearData('text/plain');
setDragImage()
拖動過程中(dragstart事件觸發(fā)后),瀏覽器會顯示一張圖片跟隨鼠標(biāo)一起移動,表示被拖動的節(jié)點。這張圖片是自動創(chuàng)造的,通常顯示為被拖動節(jié)點的外觀,不需要自己動手設(shè)置。setDragImage方法可以用來自定義這張圖片,它接受三個參數(shù),第一個是img圖片元素或者canvas元素,如果省略或為null則使用被拖動的節(jié)點的外觀,第二個和第三個參數(shù)為鼠標(biāo)相對于該圖片左上角的橫坐標(biāo)和右坐標(biāo)。
10.12 自定義事件
我們可以使用自定義事件
//新建事件實例
var event = new Event('play');
//添加監(jiān)聽函數(shù)
element.addEventListener('play',funciton(e){},false);
//觸發(fā)事件
element.dispatchEvent(event);
CustomEvent()
Event構(gòu)造函數(shù)只能指定事件名,不能在事件上綁定數(shù)據(jù)。如果需要在觸發(fā)事件的同時,傳入指定的數(shù)據(jù),需要使用CustomEvent構(gòu)造函數(shù)生成自定義的事件對象。
var event = new CustomEvent('play',{detail: 'play'});
//添加監(jiān)聽函數(shù)
element.addEventListener('play',handler,false);
//觸發(fā)事件
element.dispatchEvent(event);
CustomEvent構(gòu)造函數(shù)的第一個參數(shù)是事件名稱,第二個參數(shù)是一個對象。在上面的代碼中,該對象的detail屬性會綁定在事件對象之上。
funciton handler(e){
var data = e.detail;
}
在IE上,并不支持上面的自定義事件寫法,不過,我們可以采用老式寫法:
// 新建Event實例
var event = document.createEvent('Event');
// 事件的初始化
event.initEvent('play', true, true);
// 加上監(jiān)聽函數(shù)
document.addEventListener('play', handler, false);
// 觸發(fā)事件
document.dispatchEvent(event);
(1)document.createEvent()
document.createEvent方法用來新建指定類型的事件。它所生成的Event實例,可以傳入dispatchEvent方法。
createEvent方法接受一個字符串作為參數(shù)
(2)event.initEvent()
事件對象的initEvent方法,用來初始化事件對象,還能向事件對象添加屬性。該方法的參數(shù)必須是一個使用Document.createEvent()生成的Event實例,而且必須在dispatchEvent方法之前調(diào)用。
initEvent方法可以接受四個參數(shù)。
type:事件名稱,格式為字符串。
bubbles:事件是否應(yīng)該冒泡,格式為布爾值??梢允褂胑vent.bubbles屬性讀取它的值。
cancelable:事件是否能被取消,格式為布爾值??梢允褂胑vent.cancelable屬性讀取它的值。
option:為事件對象指定額外的屬性。
學(xué)習(xí)參考資料
書籍:《JavaScript權(quán)威指南》
文檔:MDN--觸摸事件
更多建議: