早期由于瀏覽器廠商對于瀏覽器市場的爭奪,各家瀏覽器廠商對同一功能的JavaScript的實現都不進相同,本節內容介紹JavaScript的DOM事件模型及事件處理程序的分類。
1、DOM事件模型。DOM事件模型分為兩種:事件冒泡和事件捕獲。事件冒泡最初是微軟提出的DOM事件流的模型,顧名思義,就是值瀏覽器的事件流如同冒泡一樣,從最低處到最高處。最低處對應的是DOM中最具體的元素,最高處則是最外層元素,最外層元素一般就是document元素。
a、事件冒泡模型:
如下圖,當點擊最底層的span元素時,在冒泡模型中觸發的事件流為:span的click事件觸發—->父級元素div的click事件觸發—->頂層的document元素的click事件觸發。


b、事件捕獲模型:
如下圖,當點擊span元素時,在事件捕獲模型中觸發的事件流為:最頂層的document的click事件首先被觸發—->子容器div(同時也是span的父容器)的click事件被觸發
—->最底層的span元素的click事件觸發。


可見,事件冒泡和事件捕獲的事件觸發流程是完全相反的。
2、DOM事件處理程序的分類。DOM事件處理程序分為三種:HTML事件處理程序、DOM 0級事件處理程序、DOM 2級事件處理程序(注意:、沒有DOM1級事件處理程序)。
a、HTML事件處理程序:
指的是事件綁定直接寫在HTML上,如:
1 <input type="button' value="button" onclick="alert('button clicked!')" />
這里button的click事件的綁定直接寫在HTML中,這種寫法即是HTML事件處理程序。由于這種寫法造成HTML和JavaScript的緊耦合,當需要調整JavaScript事件時,不得不調整HTML代碼(就算不修改JavaScript函數名,只修改函數的內部實現,仍然不推薦使用這種語法綁定事件,會增加不必要的維護成本)。
b、DOM 0級事件處理程序:
指的是通過給JavaScript對象的事件參數屬性賦值的模式,如:
1 <input id="btn" type="button" value="button" /> 2 <script> 3 var btn = document.getElementById("btn"); 4 btn.onclick = function(){ 5 alert("button clicked!"); 6 } 7 </script>
這里通過直接給btnDOM對象的onclick屬性賦值的形式來綁定click事件就是DOM 0級事件處理程序,賦值可以使用匿名函數的形式,也可以使用具名函數的形式,如下:
1 <input id="btn" type="button" value="button" /> 2 <script> 3 var btn = document.getElementById("btn"); 4 btn.onclick clickHandle; 5 function clickHandle(){ 6 alert("something clicked!"); 7 } 8 </script>
如需注銷,只需將該屬性設置為null即可,如下:
1 <input id="btn" type="button" value="button" /> 2 <script> 3 var btn = document.getElementById("btn"); 4 btn.onclick clickHandle; 5 function clickHandle(){ 6 alert("something clicked!"); 7 } 8 btn.onclick = null; 9 </script>
注意:如果綁定使用的是匿名函數的形式,通過給事件屬性賦值null仍然可以注銷該事件。
c、DOM 2級事件處理程序:
指的是使用 addEventListener(“eventName”,”eventHandle”,false),其中eventName表示事件名稱、eventHandle表示事件處理函數,false表示是否啟用事件捕獲模式,默認為false。使用addEventListener函數來給DOM元素綁定事件處理程序,如:
1 <input id="btn" type="button" value="button" /> 2 <script> 3 var btn = document.getElementById("btn"); 4 btn.addEventListener("click",function(){ 5 alert("something clicked!"); 6 },false); 7 </script>
同樣,這里既可以使用匿名函數的形式也可以使用具名函數的形式,如:
1 <input id="btn" type="button" value="button" /> 2 <script> 3 var btn = document.getElementById("btn"); 4 btn.addEventListener("click",clickHandle,false); 5 function clickHandle(){ 6 alert("something clicked!"); 7 } 8 </script>
注意:通過addEventListener綁定的事件只能通過removeEventListener來注銷,不能使用DOM 0級中的方式注銷事件處理程序,注銷事件如下:
1 <input id="btn" type="button" value="button" /> 2 <script> 3 var btn = document.getElementById("btn"); 4 btn.addEventListener("click",clickHandle,false); 5 function clickHandle(){ 6 alert("something clicked!"); 7 } 8 btn.removeEventListener("click",clickHandle); 9 </script>
如果綁定時使用的是匿名函數,則注銷操作比較麻煩,可以通過事件參數的callee屬性獲取當前正在執行的函數,但必須使用在事件綁定的函數內,如:
1 <script> 2 var dom=document.getElementById("content"); 3 var clickNum=0; 4 dom.addEventListener("click",function(e){ 5 clickNum++; 6 alert('你摸了我'+clickNum+'下了。最多摸2下哦'); 7 if(clickNum>=2){ 8 dom.removeEventListener(e.type,arguments.callee,false); 9 console.log(this); 10 } 11 }); 12 </script>
d、IE中DOM 2級事件處理程序的是通過attachevent來綁定的,語法與addEventListener完全一致。
e、DOM 0級和DOM 2級事件處理程序的主要區別:
DOM 2級事件處理程序可以給元素的事件綁定多個處理程序,如:
1 <input id="btn" type="button" value="button" /> 2 <script> 3 var btn = document.getElementById("btn"); 4 btn.addEventListener("click",clickHandle1,false); 5 btn.addEventListener("click",clickHandle2,false); 6 function clickHandle1(){ 7 alert("something clicked!"); 8 } 9 function clickHandle2(){ 10 alert("something clicked again!"); 11 } 12 </script>
此時,點擊btn時將會依次觸發clickHandle1、clickHandle2,注銷事件處理程序也需要針對每個事件處理程序使用removeEventListener。
DOM 0級事件處理程序如果以這種形式綁定事件,則后寫的方法會覆蓋掉之前的方法,即:
1 <input id="btn" type="button" value="button" /> 2 <script> 3 var btn = document.getElementById("btn"); 4 btn.onclick = clickHandle1(); 5 btn.onclick = clickHandle2(); 6 function clickHandle1(){ 7 alert("something clicked!"); 8 } 9 function clickHandle2(){ 10 alert("something clicked again!"); 11 } 12 </script>
這里實際只會綁定clickHandle2方法,clickHandle1被后面的clickHandle2覆蓋掉。
開發過程中推薦使用DOM 0級事件處理程序或者DOM 2級事件處理程序,如果只有一個事件處理程序DOM 0級就足夠了,當然,如需綁定多個事件處理程序,則需使用DOM 2級事件處理程序。
為了屏蔽各瀏覽器之間的實現差異,推薦使用一些JavaScript庫來輔助完成事件綁定。推薦使用jQuery,針對不同的瀏覽器,可以使用統一的接口來完成這一過程。
版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。