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