本文目的主要是爲了理解概念、記住脈絡,代碼實現方面須要本身多練習
另外,我會不斷修改完善內容,以後也會陸續附上一些拓展材料來彌補文章內容的缺失
定義:事件就是文檔或瀏覽器窗口中發生的一些特定的交互,好處不用說
概念:使用'偵聽器'來預約時間,被稱爲'觀察員模式'
使用:支持頁面行爲(js)和頁面外觀(html 和 css代碼)之間的鬆散耦合javascript
事件有兩種方式實現:
在html中直接綁定
在js中指定屬性css
解決的思路:區分究竟是什麼地方接收到這個交互,又是什麼地方須要處理這個交互,因此提出事件流的概念
實現方式:事件冒泡和事件捕獲(這個我以爲很容易理解)
書裏先把DOM2的事件模型提出來單獨舉例裏,DOM2事件流分爲三個階段:
事件捕獲1 ,目標階段2 和事件冒泡3html
事件就是用戶或瀏覽器執行某些東西,那麼響應這個事件的函數,就叫作事件處理程序(事件監聽器),通常在前面加onjava
還記得以前說說,事件有兩種實現方式:
html直接包含要執行的具體動做:
<input type='button' value="Click Me" onclick=" alert('Clicked') " />segmentfault
或者是調用js函數
<script type="text/javascript">
function showMessage(){
alert('Hello world');
}
</script>瀏覽器
<input type="button" value="Click Me" onclick="showMessage()" />函數
概念:當一個事件被觸發時,會建立一個事件對象即Event Object,既然是對象,就有屬性和方法,event的對象就是用在這個事件上的屬性和方法,會做爲參數傳遞給監聽函數的htm
type 用於獲取事件類型
target 獲取事件目標
stopPropagation() 阻止事件冒泡/捕獲
preventDefalut() 阻止事件默認行爲(只有cancelable屬性設置爲true的事件,才能夠用preventDefault()來取消默認行爲)
eventPhase屬性,用來肯定事件當前處於事件流的什麼階段,1 捕獲,2 調用,3冒泡對象
cancelBubble -- 參考stopPropagation
returnValue 默認爲true 設置爲false時取消事件的默認行爲 -- 參考preventDefault
srcElement --參考target
type事件
每一個元素(包括window和document)都有本身的事件處理程序屬性,處理程序是在元素的做用域中運行的
attachEvent()和detachEvent()
只接收兩個參數,事件,和事件處理函數,默認添加到冒泡階段
注意哦,這個事件是onclik類型的,這個跟DOM0的區別就在做用域
**DOM的做用域是元素的做用域
IE事件的做用域,是全局做用域**
還有煩的地方是,添加兩個attachEvent(),執行順序是反向的,就是後加上的先執行
吶,detachEvent()移除的條件跟DOM2是同樣的,參數必須一致,匿名函數沒法益處
addEventListener()和removeEventListener(),全部DOM節點都包含這兩個方法
接收三個參數:事件名,處理程序的函數 和 布爾值(true時捕獲階段調用,false是冒泡階段調用)
var btn=document.getElementById('myBtn');
btn.addEventListener('click',function(){xx},false);
若是添加了兩個時間處理程序,依次進行(這個很合理),
一樣經過addEventListener的 須要經過removeEventListener進行移除
拓展一下(經過addEventListener()添加的匿名函數將沒法移除,這是由於remove須要跟add添加同樣的參數,而add若是傳入了匿名函數,remove寫入的也是一個徹底不一樣的函數了)
最後 文末綜述了一個能用的EventUtil函數,把DOM 0 ,DOM2和IE都包進去,作成addEventListener和removeEventListener
一、可能頁面加載完成但處理程序沒有加載完,會出現時間差甚至拋出錯誤
二、這樣擴展事件處理程序的做用域鏈在不一樣瀏覽器中會致使不一樣結果。不一樣JavaScript引擎遵循的標識符解析規則略有差別,極可能會在訪問非限定對象成員時出錯(這個個人理解是,在js裏面,能夠根據不一樣的事件模型作對應的操做,並封裝在一個包裏,這樣用不會出錯,可是在html裏面可沒有這個技術)
三、html和javascript緊密耦合後,若是要更換就太麻煩了
因此通常經過綁定js,封裝在try-catch塊中解決問題