前言:擼完CSS-DOM緊接着來擼DOM事件,事件總結完成後我要開始總結動畫,而後用純JS實現一個輪播圖,前路漫漫,還有各類框架等着我~~~
本篇主要內容有:事件流 事件處理程序 跨瀏覽器事件處理程序javascript
--------------------? 分割線---------------------html
事件冒泡:事件開始時由最具體的元素(文檔嵌套層次最深的節點)接收,而後逐級向上傳播到較爲不具體的節點。
事件捕獲:不太具體的節點應該更早接收到事件,最具體的節點應該最後接收到事件。java
在W3C規範中:分三步(一、事件捕獲;二、事件觸發;三、事件冒泡);
在IE中:分兩步(一、事件冒泡;二、事件觸發)
在網景(Netscape):分兩步(一、事件捕獲;二、事件觸發)編程
這個在《DOM編程藝術》中初步實現的圖片庫的總結(一)就有了運用,它的js代碼嵌套在HTML中,如:想要實如今點擊按鈕時顯示一個警告框,則能夠這麼寫:segmentfault
<input type="button" value="狠狠的點我" onclick="alert('clicked')"/>
缺點:
1.代碼例子中的alert能夠換成本身定義的函數,假如用戶在頁面加載後還沒開始解析這個函數時就單擊了按鈕,這個時候就會引起錯誤,這時能夠將事件處理程序封裝在try-catch塊中,上面的代碼能夠改成:瀏覽器
<input type="button" value="狠狠的點我" onclick="try{showsomething();}catch(ex){}"/>
2.HTML和js代碼耦合性太強,若是要更換事件處理程序,就要改動兩個地方。框架
每一個元素(包括window和document)都有本身的事件處理程序屬性,例如onclick,將這種屬性值設置爲一個函數,就能夠指定事件處理程序,以下方代碼:函數
//假若有一個按鈕,先獲取這個按鈕元素 var btn = document.getElementById("myBtn"); btn.onclick = function(){ alert("你點我幹啥!!!"); };
注意:以上代碼在運行以前不會指定事件處理程序,換句話說就是若是這些代碼插入在html文檔中的最後,位於按鈕以後,body標籤以前,那麼在文檔解析這個函數以前,點擊按鈕時無效的。動畫
優勢:簡單,具備跨瀏覽器的優點this
特色:使用DOM 0級方法指定事件處理程序被認爲是元素的方法,所以這個時候事件處理是在元素的做用域中進行運行,程序中的this指向當前元素。 來看下面一段代碼:
var btn = document.getElementById("mybtn"); btn.onclick = function(){ alert(this.id); //this表明當前執行操做的元素btn,也就是id爲mybtn的按鈕 }
以上不只僅能夠訪問元素的id屬性,元素的任何屬性和方法均可以經過this訪問。以這種方式添加的事件處理程序會在事件流的冒泡階段被處理。
DOM 2級事件定義了兩個方法,分別用於處理指定和刪除事件處理程序的操做:addEventListener()
和removeEventListener()
,
他們都接收三個參數:要處理的事件名、做爲事件處理程序的函數、一個布爾值。
布爾值若是是true表示在捕獲階段調用事件處理程序,若是是false表示在冒泡階段調用事件處理程序。
添加事件操做
以下代碼:
var btn = document.getElementById("myBtn"); btn.addEventListener("click",function(){ alert(this.id); },false); btn.addEventListener("click",function(){ alert("你點我幹啥!!!"); },false);
以上代碼爲一個按鈕添加了一個onclick事件處理程序,注意裏面參數傳遞的是"click"
,這個是跟DOM中的事件類型有關,後續再說。~~~
而且使用DOM 2級方法添加事件處理程序的好處是,能夠添加多個事件處理程序,上面例子中首先會顯示元素id,而後顯示"你點我幹啥!!!"。
刪除事件操做
經過addEventListener()添加的事件處理程序只能使用removeEventListener()來移除,移除時傳入的參數與添加程序時使用的參數相同。這也就意味着經過addEventListener()添加的匿名函數將沒法移除。如上面的例子,我增長如下代碼將沒法移除事件:
btn.removeEventListener("click",function(){ alert(this.id); },false);
解決辦法是,將上面的匿名函數賦值給一個變量,而後adddEventListener和 removeEventListener
傳參數時傳入這個變量就能夠了。
重寫這個函數以下:
var btn = document.getElementById("myBtn"); var handler = function(){ alert(this.id); }; btn.addEventListener("click",handler,false); btn.addEventListener("click",handler,false);
----------------- 珍愛生命,遠離IE ------------------
IE也實現了DOM中的相似的兩個方法:attachEvent() 和detachEvent(),這兩個方法接受相同的兩個參數,事件處理程序名稱與事件處理程序函數。
以下代碼:
var btn = document.getElementById("mybtn"); btn.attachEvent("onclick",function(){ //你沒看錯,用的「onclick」!!! alert("你又點我了!!!"); });
注意:
1.attachEvent()的第一個參數時「onclick」
2.使用attachEvent(),事件處理程序會在全局做用域中進行,所以this===window
3.添加多個事件時,事件處理程序不是以添加它們的順序執行,而是以相反的順序被觸發。
4.使用detachEvent()來移除時,匿名函數一樣不能移除,所以須要傳遞給函數相同的引用。
那麼重點來了,能夠封裝一個對象解決跨瀏覽器進行事件處理,給這個對象起名叫:EventUtil,它有兩個方法,分別進行事件添加和移除。
且看下面代碼:
var EventUtil = { //@handler是裝載匿名函數的引用變量,裏面裝載的是具體要執行的函數邏輯 //@element是目標元素 //type表明的是DOM 2級的事件類型,所以在用IE或者DOM 0級前面要加「on」 addHandler: function (element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent("on" + type, handler); } else { elemet["on" + type] = handler; //若是上面兩種都不行,就使用DOM 0級方法處理,直接在元素上添加onclick事件 } }, removeHandler: function (element, type, handler) { if (element.removeEventListener) { element.removeEventListener(type, handler, false); } else if (element.detachEvent) { element.detachEvent("on" + type, handler); } else { element["on" + type] = null; ////若是上面兩種都不行,就使用DOM 0級方法處理,直接賦值爲null取消事件 } } };
定義好了,怎麼使用呢?看下面~~~
var btn = document.getElementById("myBtn"); var handler = function(){ alert("你又點我了!!!"); }; //添加事件 EventUtil.addHandler(btn,"click",handler); //移除事件 EventUtil.removeHandler(btn,"click",handler);
以上代碼並無考慮IE中的做用域問題,而且DOM 0級只支持一個事件處理程序,但也不是什麼問題,現在只賣早餐的飯店很少了~~~
此次沒有源代碼,以上~