輕松學習JavaScript二十七:DOM編程學習之事件模型
在介紹事件模型之前,我們先來看什麽是事件和什麽是event對象。
一事件介紹
JavaScript事件是由訪問Web頁面的用戶引起的一系列操作,使我們有能力創建動態頁面。事件是能夠被
JavaScript偵測到的行為。
網頁中的每一個元素都能夠產生某些能夠觸發JavaScript函數的事件。例如說。我們能夠在用
戶點擊某button時產生一個onclick事件來觸發某個函數。事件在HTML頁面中定義;事件通常與函數配合使用,當事件
發生時函數才會運行;事件一般用於瀏覽器和用戶操作進行交互。
我們經經常使用到的事件舉例:鼠標點擊,頁面或圖像加載,鼠標懸浮於頁面的某個熱點之上,在表單中選取輸入
框,確認表單。鍵盤按鍵等等。
二event對象
Event對象代表事件的狀態,比方事件在當中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標button的狀態。
事
件通常與函數結合使用,函數不會在事件發生前被運行!
當觸發某個事件時,會產生一個事件對象。這個對象包括著全部與事件有關的信息。包括導致事件的元素。事件
的類型,以及其他與特定事件相關的信息。事件對象我們一般稱作event對象。這個對象是瀏覽器通過函數把這個對
象作為參數傳遞過來的。那麽我們能夠驗證一下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>DOM</title> <script type="text/javascript"> //定義的普通函數 function box(){ alert(arguments.length);//輸出:0 }; //函數調用 box(); window.onload=function(){ //得到input對象 var input=document.getElementsByTagName("input")[0]; //匿名函數運行 input.onclick=function(){ alert(arguments.length);//輸出:1,得到一個隱藏的參 alert(arguments[0]);//輸出:object MouseEvent表示鼠標事件對象 }; } </script> </head> <body> <input type="button" value="按鈕" /> </body> </html>
通過上面兩組函數,我們得到。通過事件綁定的運行函數是能夠得到一個隱藏參數的,說明瀏覽器會自己主動分配一
個參數,這個參數就是為event對象。我們是能夠直接接受event對象的,W3C和IE分別用不同的方法得到:W3C的是
直接傳遞event對象作為參數,而IE須要使用window.evevt才幹獲取得到。
我們來做一下兼容:
window.onload=function(){ //得到input對象 var input=document.getElementsByTagName("input")[0]; //匿名函數運行 input.onclick=function(event){ var event=event||window.event; alert(event);//輸出:object MouseEvent表示鼠標事件對象 }; }
我們既然得到event對象,因此我們能夠操作一些event對象的屬性和方法:
標準Event屬性
標準Event方法
因為DOM2級標準事件模型,IE9之前的低版本號瀏覽器並不支持。IE9已經全面支持了。我們就不再做瀏覽器兼容
的屬性和方法。
在真正用到的時候我們再進行視情況而定的兼容。
三事件模型
(1)內聯模型
內聯模型是最傳統接單的一種處理事件的方法。在內聯模型中,事件處理函數是HTML標簽的一個屬性。用於處
理指定事件。盡管內聯在早期使用較多,可是它是和html混寫的,並沒有與html分離,而且寫入的代碼數量非常少,並
不有用。
以下看一個內聯模型的演示樣例:
<!--在HTML中把事件處理函數作為屬性運行JS代碼--> <input type="button" value="按鈕" onclick="alert('I am JS code!');" />
另一個內聯模型的應用,這個也實現了JS代碼和HTML一定的分離。但還是屬於內聯模型。JS函數寫在JS文件
中:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>DOM</title> <script type="text/javascript"> function box(){ alert("I am JS code!"); } </script> </head> <body> <!--在HTML中把事件處理函數作為屬性運行JS函數--> <input type="button" value="按鈕" onclick="box();" /> </body> </html>
(2)腳本模型
因為內聯模型違反了HTML與JavaScript代碼層次分離的原則,為了解決問題。我們嘗試在JavaScript中進行
事件處理。這樣就產生了腳本模型。示比例如以下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>DOM</title> <script type="text/javascript"> window.onload=function(){ //得到input對象 var input=document.getElementsByTagName("input")[0]; //匿名函數運行 input.onclick=function(){ alert("I am JS code!"); }; } </script> </head> <body> <input type="button" value="按鈕" /> </body> </html>
通過匿名函數能夠運行onclick事件,即能夠直接觸發相應的代碼。還有還有一種方式也能夠實現,那就是通過指定
的函數名賦值的方式來運行函數,註意賦值的函數名不要帶著括號。
和上面有差別的就是JS代碼部分:
window.onload=function(){ //得到input對象 var input=document.getElementsByTagName("input")[0]; //通過賦值指定的函數名運行 input.onclick=box; function box(){ alert("I am JS code!"); }; }
(3)DOM2級模型
在介紹DOM2模型之前我們的先了解什麽是事件流。
事件流是描寫敘述的從頁面接受事件的順序,當幾個都具有事件的元素層疊在一起的時候,那麽你點擊當中一個元
素。並非僅僅有當前被點擊的元素會觸發事件,而層疊在你點擊範圍內的全部元素都會出發事件。事件流包含兩種模
式:冒泡和捕獲。
以下的圖示非常好的展示了事件流:
事件冒泡,是從裏往外逐個觸發。事件捕獲。是從外往裏逐個觸發。
現代瀏覽器默認情況下都是冒泡模型。我們
能夠使用DOM2級模型的事件綁定機制手動定義事件流模式。
在全部的現代瀏覽器其中——除了IE9之前的版本號,都實現了DOM2標準事件模型。這個事件模型規定:每個
DOM元素所觸發的事件都要經歷三個階段:捕獲階段;目標對象本身的事件處理程序調用階段;冒泡階段。
冒泡階段:當文檔元素上發生某個類型的事件時。他們會在文檔樹上向上傳播,即調用父元素的同樣類型的事件
處理函數。
捕獲階段:捕獲階段像是反向的冒泡階段。
最先調用window對象的捕獲處理程序,然後是document對象的捕獲處
理程序,接著是body對象的,再然後是Dom樹向下。以此類推。直到調用事件目標元素的父元素的捕獲事件處理程
序。在目標元素對象本身上註冊捕獲事件處理程序不會被調用。
在DOM2級標準事件模型中。為一個DOM元素綁定事件的方法是addEventListener()方法,這種方法要求傳遞三
個參數,第一個參數為一個字符串。表示事件的類型。如"click";第二個參數是一個函數。表示事件處理程序,瀏覽
器會默覺得該函數傳遞一個事件對象也就是event對象;第三個參數是一個布爾值,布爾值為false表示此函數將註冊
為冒泡事件處理程序(通常設置為false就可以),假設值為true,表示此函數將註冊為捕獲事件處理程序。值得註意的
是,能通過多次調用addEventListener()方法為同一個對象註冊同一事件類型的多個處理程序函數。當對象上發生事
件時,全部該事件類型的註冊處理程序都會依照註冊的順序調用。
分析事件的觸發過程,分兩種情況:
1當目標元素不存在父元素或目標元素的父元素並沒有註冊與觸發目標元素同樣類型的事件時,事件模型的第一
和第三階段是沒有實際意義的,即不會發生不論什麽的事情。
2當目標元素存在父元素且目標元素的父元素註冊了與觸發目標元素同樣類型的事件時。事件模型的第一和第三
階段就開始起作用了。
我們在這裏看一個非常easy的樣例:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>DOM</title> <script type="text/javascript"> window.addEventListener("load",function(){ alert("I am JS code!"); },false) </script> </head> <body> <input type="button" value="按鈕" /> </body> </html>
上面的addEventListener()方法IE9之前的低版本號瀏覽器並不兼容,而且進行綁定的時候會有諸多的問題出現。IE
不支持捕獲,僅僅支持冒泡;IE加入事件不能屏蔽反復的函數。IE中的this指向的是window對象而不是DOM對象。可能
對於低版本號的IE瀏覽器不兼容。可是IE9全然支持W3C中的事件綁定函數。
對於怎麽做到兼容。還是在詳細的實際項
目中靈活應用。
輕松學習JavaScript二十七:DOM編程學習之事件模型