事件(上)
JavaScript事件列表 | ||
事件 | 解說 | |
一般事件 | onclick | 鼠標(biāo)點(diǎn)擊時(shí)觸發(fā)此事件 |
ondblclick | 鼠標(biāo)雙擊時(shí)觸發(fā)此事件 | |
onmousedown | 按下鼠標(biāo)時(shí)觸發(fā)此事件 | |
onmouseup | 鼠標(biāo)按下后松開鼠標(biāo)時(shí)觸發(fā)此事件 | |
onmouseover | 當(dāng)鼠標(biāo)移動(dòng)到某對象范圍的上方時(shí)觸發(fā)此事件 | |
onmousemove | 鼠標(biāo)移動(dòng)時(shí)觸發(fā)此事件 | |
onmouseout | 當(dāng)鼠標(biāo)離開某對象范圍時(shí)觸發(fā)此事件 | |
onkeypress | 當(dāng)鍵盤上的某個(gè)鍵被按下并且釋放時(shí)觸發(fā)此事件. | |
onkeydown | 當(dāng)鍵盤上某個(gè)按鍵被按下時(shí)觸發(fā)此事件 | |
onkeyup | 當(dāng)鍵盤上某個(gè)按鍵被按放開時(shí)觸發(fā)此事件 | |
頁面相關(guān)事件 | onabort | 圖片在下載時(shí)被用戶中斷 |
onbeforeunload | 當(dāng)前頁面的內(nèi)容將要被改變時(shí)觸發(fā)此事件 | |
onerror | 出現(xiàn)錯(cuò)誤時(shí)觸發(fā)此事件 | |
onload | 頁面內(nèi)容完成時(shí)觸發(fā)此事件 | |
onmove | 瀏覽器的窗口被移動(dòng)時(shí)觸發(fā)此事件 | |
onresize | 當(dāng)瀏覽器的窗口大小被改變時(shí)觸發(fā)此事件 | |
onscroll | 瀏覽器的滾動(dòng)條位置發(fā)生變化時(shí)觸發(fā)此事件 | |
onstop | 瀏覽器的停止按鈕被按下時(shí)觸發(fā)此事件或者正在下載的文件被中斷 | |
oncontextmenu | 當(dāng)彈出右鍵上下文菜單時(shí)發(fā)生 | |
onunload | 當(dāng)前頁面將被改變時(shí)觸發(fā)此事件 | |
表單相關(guān)事件 | onblur | 當(dāng)前元素失去焦點(diǎn)時(shí)觸發(fā)此事件 |
onchange | 當(dāng)前元素失去焦點(diǎn)并且元素的內(nèi)容發(fā)生改變而觸發(fā)此事件 | |
onfocus | 當(dāng)某個(gè)元素獲得焦點(diǎn)時(shí)觸發(fā)此事件 | |
onreset | 當(dāng)表單中RESET的屬性被激發(fā)時(shí)觸發(fā)此事件 | |
onsubmit | 一個(gè)表單被遞交時(shí)觸發(fā)此事件 |
了解上面的事件如此簡單,那么事件還有什么可講的呢?
問題一:每個(gè)事件只能注冊一個(gè)函數(shù)





解決方案一:





缺陷一:需要將所有函數(shù)一次添加進(jìn)去,不能在運(yùn)行時(shí)添加
缺陷二:在事件處理函數(shù)中this將指向window,而不是obj
解決方案二:















這樣已經(jīng)解決了問題,但如何刪除事件呢?如果直接將對象的onevtype這類的屬性賦值為null將會刪除所有的事件處理函數(shù)!
解決方案二的修改版:先將事件存儲起來,存儲在對象的__EventHandles屬性里面



























使用上面的函數(shù)已經(jīng)可以在一個(gè)對象添加多個(gè)事件處理函數(shù),在函數(shù)內(nèi)部this關(guān)鍵字也指向了相應(yīng)的對象,并且這些函數(shù)都被作了標(biāo)識,那么移除某個(gè)事件處理函數(shù)就是輕而易舉的了!









事件(下)
事件對象——Event
事件對象是用來記錄一些事件發(fā)生時(shí)的相關(guān)信息的對象。事件對象只有事件發(fā)生時(shí)才會產(chǎn)生,并且只能是事件處理函數(shù)內(nèi)部訪問,在所有事件處理函數(shù)運(yùn)行結(jié)束后,事件對象就被銷毀!
訪問事件對象:W3C DOM方法與IE專用方法










事件對象的屬性及方法
屬性名 | 值類型 | 讀/寫 | 描述 |
---|---|---|---|
button | Integer | R |
對于特定的鼠標(biāo)事件,表示按下的鼠標(biāo)按鈕,該屬性僅可以在mouseup與mousedown事件中訪問。W3C 規(guī)定:0表示按下了左鍵,1表示按下了中鍵,2表示按下了右鍵,相當(dāng)于對于鼠標(biāo)鍵從左到右進(jìn)行的編號,而編號從0開始; 而IE有另外一套規(guī)定:0表示沒有任何鍵按下,1表示左鍵,2表示右鍵,4表示中鍵,而其它按鍵的組合則只要將鍵碼相加即可,如:同時(shí)按下左右鍵時(shí)button值為3 |
clientX | Integer | R | 事件發(fā)生時(shí),鼠標(biāo)在客戶端區(qū)域的X坐標(biāo),客戶端區(qū)域是指頁面可視區(qū)域 |
clientY | Integer | R | 事件發(fā)生時(shí),鼠標(biāo)在客戶端區(qū)域的Y坐標(biāo) |
screenX | Integer | R(IE) R/W(W3C) | 相對于屏幕的鼠標(biāo)X坐標(biāo) |
screenY | Integer | R(IE) R/W(W3C) | 相對于屏幕的鼠標(biāo)Y坐標(biāo) |
x(僅IE) | Integer | R | 鼠標(biāo)相對于引起事件的元素的父元素的X坐標(biāo) |
y(僅IE) | Integer | R | 鼠標(biāo)相對于引起事件的元素的父元素的Y坐標(biāo) |
offsetX(僅IE) layerX(僅W3C) | Integer | R | 鼠標(biāo)相對于引起事件的對象的X坐標(biāo) |
offsetY(僅IE) layerY(僅W3C) | Integer | R | 鼠標(biāo)相對于引起事件的對象的Y坐標(biāo) |
pageX(僅W3C) | Integer | R | 鼠標(biāo)相對于頁面的X坐標(biāo) |
pageY(僅W3C) | Integer | R | 鼠標(biāo)相對于頁面的Y坐標(biāo) |
屬性名 | 值類型 | 讀/寫 | 描述 |
---|---|---|---|
altKey | Boolean | R | true表示按下了ALT鍵;false表示沒有按下 |
ctrlKey | Boolean | R | true表示按下了CTROL,false表示沒有 |
shiftKey | Boolean | R | true表示按下了shift,false表示沒有 |
keyCode | Integer | R/W(IE) R(W3C) | 對于keypress事件,表示按下按鈕的Unicode字符;對于keydown/keyup事件 ,表示按下按鈕的數(shù)字代號 |
charCode(僅W3C) | Integer | R | 在keypress事件中所按鍵的字符Unicode編碼,如果不是字符鍵,則該屬性為0,并且,當(dāng)CapsLock打開與關(guān)閉時(shí)charCode的值也對應(yīng)著大小寫字母 |
屬性名 | 值類型 | 讀/寫 | 描述 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
srcElement(IE) target(W3C) | Element | R | 引起事件的元素 | ||||||||
fromElement(僅IE) | Element | R | 某些鼠標(biāo)事件中(mouseover與mouseout),鼠標(biāo)所離開的元素 | ||||||||
toElement(僅IE) | Element | R | 某些鼠標(biāo)事件中(mouseover與mouseout),鼠標(biāo)所進(jìn)入的元素 | ||||||||
relatedTarget(僅W3C) | Element | R | 某些鼠標(biāo)事件中(mouseover與mouseout),返回與事件的目標(biāo)節(jié)點(diǎn)相關(guān)的節(jié)點(diǎn)。 | ||||||||
repeat(僅IE) | Boolean | R | 如果不斷觸發(fā)keydown事件,則為true,否則為false | ||||||||
returnValue(僅IE) | Boolean | R/W | 將其設(shè)為false表示以取消事件的默認(rèn)動(dòng)作 | ||||||||
preventDefault(僅W3C) | Function | R | 執(zhí)行方法以取消事件的默認(rèn)動(dòng)作 | ||||||||
type | String | R | 事件的名稱,不帶on前綴 | ||||||||
cancelable(僅W3C ) | Boolean | R | 當(dāng)為true表示事件的默認(rèn)動(dòng)作可以被取消(用preventDefault方法取消) | ||||||||
cancelBubble(僅IE) | Boolean | R/W | 將其設(shè)置為true將取消事件冒泡 | ||||||||
stopPropagation(僅W3C) | Function | R | 執(zhí)行方法取消事件冒泡 | ||||||||
bubbles(僅W3C) | Boolean | R | 返回true表示事件是冒泡類型 | ||||||||
eventPhase(僅W3C) | Integer | R | 返回事件傳播的當(dāng)前階段。它的值是下面的三個(gè)常量之一,它們分別表示捕獲階段、在目標(biāo)對象上時(shí)和起泡階段:
|
||||||||
timeStamp (僅W3C) | Long | R | 返回一個(gè)時(shí)間戳。指示發(fā)生事件的日期和時(shí)間(從 epoch 開始的毫秒數(shù))。epoch 是一個(gè)事件參考點(diǎn)。在這里,它是客戶機(jī)啟動(dòng)的時(shí)間。并非所有系統(tǒng)都提供該信息,因此,timeStamp 屬性并非對所有系統(tǒng)/事件都是可用的。 |
取得事件對象及取得事件目標(biāo)對象






阻止事件發(fā)生時(shí)瀏覽器的默認(rèn)行為



















事件傳播——冒泡與捕獲
DOM事件標(biāo)準(zhǔn)定義了兩種事件流,這兩種事件流有著顯著的不同并且可能對你的應(yīng)用有著相當(dāng)大的影響。這兩種事件流分別是捕獲和冒泡。和許多Web技術(shù)一樣,在它們成為標(biāo)準(zhǔn)之前,Netscape和微軟各自不同地實(shí)現(xiàn)了它們。Netscape選擇實(shí)現(xiàn)了捕獲事件流,微軟則實(shí)現(xiàn)了冒泡事件流。幸運(yùn)的是,W3C決定組合使用這兩種方法,并且大多數(shù)新瀏覽器都遵循這兩種事件流方式。
默認(rèn)情況下,事件使用冒泡事件流,不使用捕獲事件流。然而,在Firefox和Safari里,你可以顯式的指定使用捕獲事件流,方法是在注冊事件時(shí)傳入useCapture參數(shù),將這個(gè)參數(shù)設(shè)為true。
冒泡事件流
當(dāng)事件在某一DOM元素被觸發(fā)時(shí),例如用戶在客戶名字節(jié)點(diǎn)上點(diǎn)擊鼠標(biāo),事件將跟隨著該節(jié)點(diǎn)繼承自的各個(gè)父節(jié)點(diǎn)冒泡穿過整個(gè)的DOM節(jié)點(diǎn)層次,直到它遇到依附有該事件類型處理器的節(jié)點(diǎn),此時(shí),該事件是onclick事件。在冒泡過程中的任何時(shí)候都可以終止事件的冒泡,在遵從W3C標(biāo)準(zhǔn)的瀏覽器里可以通過調(diào)用事件對象上的stopPropagation()方法,在Internet Explorer里可以通過設(shè)置事件對象的cancelBubble屬性為true。如果不停止事件的傳播,事件將一直通過DOM冒泡直至到達(dá)文檔根。
捕獲事件流
事件的處理將從DOM層次的根開始,而不是從觸發(fā)事件的目標(biāo)元素開始,事件被從目標(biāo)元素的所有祖先元素依次往下傳遞。在這個(gè)過程中,事件會被從文檔根到事件目標(biāo)元素之間各個(gè)繼承派生的元素所捕獲,如果事件監(jiān)聽器在被注冊時(shí)設(shè)置了useCapture屬性為true,那么它們可以被分派給這期間的任何元素以對事件做出處理;否則,事件會被接著傳遞給派生元素路徑上的下一元素,直至目標(biāo)元素。事件到達(dá)目標(biāo)元素后,它會接著通過DOM節(jié)點(diǎn)再進(jìn)行冒泡。
現(xiàn)代事件綁定方法
針對如上節(jié)課所討論的,使用傳統(tǒng)事件綁定有許多缺陷,比如不能在一個(gè)對象的相同事件上注冊多個(gè)事件處理函數(shù)。而瀏覽器和W3C也并非沒有考慮到這一點(diǎn),因此在現(xiàn)代瀏覽器中,它們有自己的方法綁定事件。
W3C DOM
- obj.addEventListener(evtype,fn,useCapture)——W3C提供的添加事件處理函數(shù)的方法。obj是要添加事件的對象,evtype是事件類型,不帶on前綴,fn是事件處理函數(shù),如果useCapture是true,則事件處理函數(shù)在捕獲階段被執(zhí)行,否則在冒泡階段執(zhí)行
- obj.removeEventListener(evtype,fn,useCapture)——W3C提供的刪除事件處理函數(shù)的方法
微軟IE方法
- obj.attachEvent(evtype,fn)——IE提供的添加事件處理函數(shù)的方法。obj是要添加事件的對象,evtype是事件類型,帶on前綴,fn是事件處理函數(shù),IE不支持事件捕獲
- obj.detachEvent(evtype,fn,)——IE提供的刪除事件處理函數(shù)的方法,evtype包含on前綴
整合兩者的方法


















其它兼容性問題:IE不支持事件捕獲?很抱歉,這個(gè)沒有辦法解決!但I(xiàn)E的attach方法有個(gè)問題,就是使用attachEvent時(shí)在事件處理函數(shù)內(nèi)部,this指向了window,而不是obj!當(dāng)然,這個(gè)是有解決方案的!











但I(xiàn)E的attachEvent方法有另外一個(gè)問題,同一個(gè)函數(shù)可以被注冊到同一個(gè)對象同一個(gè)事件上多次,解決方法:拋棄IE的 attachEvent方法吧!IE下的attachEvent方法不支持捕獲,和傳統(tǒng)事件注冊沒多大區(qū)別(除了能綁定多個(gè)事件處理函數(shù)),并且IE的 attachEvent方法存在內(nèi)存泄漏問題!
addEvent,delEvent現(xiàn)代版










































標(biāo)準(zhǔn)化事件對象
IE的事件對象與W3C DOM的事件對象有許多不一樣的地方,解決的最好的方法就是調(diào)整IE的事件對象,以使它盡可能的與標(biāo)準(zhǔn)相似!下表列出了IE事件對象中一些和W3C DOM名稱或值不一樣但含義相同的屬性
W3C DOM | IE |
---|---|
button——按鍵編碼為:0-左鍵,1-中鍵,2-右鍵 | button——按鍵編碼為:1-左鍵,2-右鍵,4-中鍵 |
charCode | 沒有對應(yīng)屬性,但可以用keyCode來代替 |
preventDefault | 沒有對應(yīng)方法,但可以將event對象的returnValue設(shè)為false來模擬 |
target | srcElement |
relatedTarget | fromElement與toElement |
stopPropagation | 沒有對應(yīng)方法,但可以通過將event對象的cancelBubble屬性設(shè)為true來模擬 |
總結(jié)出fixEvent函數(shù)






















fixEvent函數(shù)不是單獨(dú)執(zhí)行的,它必須有一個(gè)事件對象參數(shù),而且只有事件發(fā)生時(shí)它才被執(zhí)行!最好的方法是把它整合到addEvent函數(shù)的execEventHandles里面









Load事件
使用JavaScript操縱DOM,必須等待DOM加載完畢才可以執(zhí)行代碼,但window.onload有個(gè)壞處,它非要等到頁面中的所有圖片及視頻加載完畢才會觸發(fā)load事件。結(jié)果就是一些本來應(yīng)該在打開時(shí)隱藏起來的元素,由于網(wǎng)絡(luò)延遲,在頁面打開時(shí)仍然會出現(xiàn),然后又會突然消失,讓用戶覺得莫名其妙。
大師們想出來的方法:


































from :http://www.javaeye.com/topic/517899