DOM事件總結(一)

前言:擼完CSS-DOM緊接着來擼DOM事件,事件總結完成後我要開始總結動畫,而後用純JS實現一個輪播圖,前路漫漫,還有各類框架等着我~~~
本篇主要內容有:事件流 事件處理程序 跨瀏覽器事件處理程序javascript

--------------------? 分割線---------------------html

1.事件流

事件冒泡:事件開始時由最具體的元素(文檔嵌套層次最深的節點)接收,而後逐級向上傳播到較爲不具體的節點。
事件捕獲:不太具體的節點應該更早接收到事件,最具體的節點應該最後接收到事件。java

2.DOM事件流

在W3C規範中:分三步(一、事件捕獲;二、事件觸發;三、事件冒泡);
在IE中:分兩步(一、事件冒泡;二、事件觸發)
在網景(Netscape):分兩步(一、事件捕獲;二、事件觸發)編程

3.事件處理程序

(一)HTML事件處理程序

這個在《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代碼耦合性太強,若是要更換事件處理程序,就要改動兩個地方。框架

(二)DOM 0級事件處理程序

每一個元素(包括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級事件處理程序

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);

(4)跨瀏覽器的事件處理程序

----------------- 珍愛生命,遠離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級只支持一個事件處理程序,但也不是什麼問題,現在只賣早餐的飯店很少了~~~

此次沒有源代碼,以上~

相關文章
相關標籤/搜索