一、什么是JavaScript事件? |
? ?
?
? ? ? 事件(Event)是JavaScript應用跳動的心臟,也是把所有東西粘在一起的膠水,當我們與瀏覽器中Web頁面進行某些類型的交互時,事件就發生了。
? ? ? 事件可能是用戶在某些內容上的點擊、鼠標經過某個特定元素或按下鍵盤上的某些按鍵,事件還可能是Web瀏覽器中發生的事情,比如說某個Web頁面加載完成,或者是用戶滾動窗口或改變窗口大小。說白了,事件是文檔或瀏覽器中發生的特定交互瞬間!
? ? ? 通過使用JavaScript,你可以監聽特定事件的發生,并規定讓某些事件發生以對這些事件做出響應。
?
二、事件流 |
?
?
? ? ? 事件流就是描述了頁面中接受事件的順序,在瀏覽器發展的初期,兩大瀏覽器廠商IE和Netscape互掐,出現了一個坑爹的情況,那就是他們對事件流的解釋出現了兩中截然相反的定義。也就是我們所熟悉的:IE的事件冒泡,Netscape的事件捕獲。先來一張圖,簡要的看下結構:
? ? ? 1、事件冒泡
? ? ? 事件冒泡即事件最開始由最具體的元素(文檔中嵌套層次最深的那個節點)接收,然后逐級向上傳播至最不具體的節點(文檔)。拿上面的圖來說明,就是當點擊text部分時,先由text處的元素接收,然后逐級傳播至window,即執行6-7-8-9-10的過程。
? ? ? 2、事件捕獲
? ? ? 事件捕獲即事件最早由不太具體的節點接收,而最具體的節點最后接收到事件。同理,在上面的模型中,就是點擊text部分時,先由window接收,然后逐級傳播至text元素,即執行1-2-3-4-5的過程。
具體在代碼中怎樣表現呢?后面給出!
?
三、Javascript事件處理程序的3種方式 |
?
? ? ?
? ? ? 產生了事件,我們就要去處理他,Javascript事件處理程序主要有3種方式:
? ? ? 1、HTML事件處理程序
? ? ? 即我們直接在HTML代碼中添加事件處理程序,如下面這段代碼:
1 <input id="btn1" value="按鈕" type="button" onclick="showmsg();"> 2 <script> 3 function showmsg(){ 4 alert("HTML添加事件處理"); 5 } 6 </script>
? ? ? 從上面的代碼中我們可以看出,事件處理是直接嵌套在元素里頭的,這樣有一個毛病:就是html代碼和js的耦合性太強,如果哪一天想要改變js中showmsg,那么不但要再js中修改,還需要到html中修改,一兩處的修改我們能接受,但是當你的代碼達到萬行級別的時候,修改起來就需要勞民傷財了,所以,這個方式我們并不推薦使用。
? ? ? 2、DOM0級事件處理程序
? ? ? 即為指定對象添加事件處理,看下面的一段代碼:
1 <input id="btn2" value="按鈕" type="button"> 2 <script> 3 var btn2= document.getElementById("btn2"); 4 btn2.onclick=function(){ 5 alert("DOM0級添加事件處理"); 6 } 7 btn.onclick=null;//如果想要刪除btn2的點擊事件,將其置為null即可 8 </script>
? ? ? 從上面的代碼中,我們能看出,相對于HTML事件處理程序,DOM0級事件,html代碼和js代碼的耦合性已經大大降低。但是,聰明的程序員還是不太滿足,期望尋找更簡便的處理方式,下面來看第三種處理方法。? ?
? ? ? 3、DOM2級事件處理程序
? ? ? DOM2也是對特定的對象添加事件處理程序,但是主要涉及到兩個方法,用于處理指定和刪除事件處理程序的操作:addEventListener()和 removeEventListener()。它們都接收三個參數:要處理的事件名、作為事件處理程序的函數和一個布爾值(是否在捕獲階段處理事件),看下面的一段代碼:
1 <input id="btn3" value="按鈕" type="button"> 2 <script> 3 var btn3=document.getElementById("btn3"); 4 btn3.addEventListener("click",showmsg,false);//這里我們把最后一個值置為false,即不在捕獲階段處理,一般來說冒泡處理在各瀏覽器中兼容性較好 5 function showmsg(){ 6 alert("DOM2級添加事件處理程序"); 7 } 8 btn3.removeEventListener("click",showmsg,false);//如果想要把這個事件刪除,只需要傳入同樣的參數即可 9 </script>
? ? ? 這里我們可以看到,在添加刪除事件處理的時候,最后一種方法更直接,也最簡便。但是馬海祥提醒大家需要注意的是,在刪除事件處理的時候,傳入的參數一定要跟之前的參數一致,否則刪除會失效!
?
四、事件冒泡和事件捕獲的流程與區別 |
?
?
? ? ? 說到這里,再給大家來一點代碼來說明下事件冒泡和事件捕獲的流程,同時也讓大家能看出二者的區別:
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 #p{width:400px;height:200px;border:1px solid black;} 8 #c{width:200px;height:100px;border:1px solid red;} 9 </style> 10 </head> 11 <body> 12 <div id="p"> 13 i am www.mahaixiang.cn 14 <div id="c">i like www.mahaixiang.cn</div> 15 </div> 16 <script> 17 var p = document.getElementById('p'); 18 var c = document.getElementById('c'); 19 c.addEventListener('click', function () { 20 alert('子節點捕獲') 21 }, true); 22 c.addEventListener('click', function () { 23 alert('子節點冒泡') 24 }, false); 25 p.addEventListener('click', function () { 26 alert('父節點捕獲') 27 }, true); 28 p.addEventListener('click', function () { 29 alert('父節點冒泡') 30 }, false); 31 </script> 32 </body> 33 </html>
?
? ? ? 運行上面的代碼,點擊子元素的時候,我們會發現,執行的先后順序是:父節點捕獲--子節點捕獲--子節點冒泡--父節點冒泡。從這個例子中,大家也就明白了,另外,DOM2級事件規定事件包括三個階段:
? ? ? 1、事件捕獲階段;
? ? ? 2、處于目標階段;
? ? ? 3、事件冒泡階段。
? ? ? 首先是捕獲,然后處于目標階段(即來到事件的發出位置),最后才是冒泡,不科學的是,居然木有DOM1級事件處理程序,大家注意下,別鬧出笑話了!
五、補充 |
?
? ? ?
? ? ? 1. IE事件處理程序也對應有兩個方法:attachEvent()添加事件,detachEvent()刪除事件,這兩個方法接收相同的兩個參數:事件處理程序名稱與事處理函數。這里為什么沒有布爾值呢?因為ie8以及更早的版本只支持事件冒泡,所以最后一個參數默認的相當于false來處理!(支持IE事件處理程序的瀏覽器有IE,opera)。
? ? ? 2.?事件對象是用來記錄一些事件發生時的相關信息的對象,但事件對象只有事件發生時才會產生,并且只能是事件處理函數內部訪問,在所有事件處理函數運行結束后,事件對象就被銷毀!
?
? ? ? 文章轉自:?http://www.mahaixiang.cn/js/694.html
?