關於事件兼容性

DOM事件

事件咱們常常用到,用起來也比較簡單,今天咱們主要聊一下DOM事件流、事件的兼容性、事件代理。javascript

DOM事件流

DOM處理事件的流程java

事件傳遞的3個過程node

  • capture phase :事件的捕獲過程;從DOM樹的最頂端,直到捕獲到出發這個事件的節點的父元素
  • target phase:事件的觸發過程
  • bubble phase:事件的冒泡階段,將會從當前節點的父節點開始,一直冒泡到window對象

這3個流程由W3C規定,可是在IE的低版本里並無第一個捕獲的過程;
並非全部事件都有這3個過程,有些事件是沒有冒泡的過程,例如頁面load事件沒有冒泡過程。瀏覽器


事件兼容性

註冊事件、取消註冊、觸發事件、事件對象和事件源、阻止事件傳播、取消默認行爲等在IE瀏覽器中和其餘瀏覽器是有區別的,下面咱們逐一來看一下函數

註冊事件

事件的註冊常常用到,你們都是比較熟悉的,須要注意的是兼容性的問題。性能

// IE之外
// type  事件類型 
// listener 事件處理函數
//最後一個參數可選的:若是是true那麼事件句柄在在捕獲節點執行;若是是false則事件句柄在冒泡階段執行

elem.addaEventListener(type,listener [,useCapture])

// 實例
elem.addEventListener('click',clickhandler,false);
function clickhandler(){
    // do something
}

IE中是這樣的spa

// IE
// type 事件類型
// listener 事件處理函數
// IE中沒有捕獲階段 所以沒有第三個參數
elem.attachEvent(type,listener);

// 實例
elem.attachEvent('onclick',handler);//事件名稱 含 'on'

function handler(){
    // do something 
}

咱們能夠作一個兼容的方法,還比較容易理解的。代理

function addEvent(elem,type,listener){
    if(elem.addEventListener){
        elem.addEventListener(type,listener,false);
    }
    if(elem.attachEvent){
        elem.attachEvent('on'+type,listener)
    }
}

取消註冊

//接受參數和addEventListener一致
//IE之外
elem.removeEventListener(type,listener [,useCapture]);

//IE
elem.detachEvent(type,listener)

觸發事件

某些狀況下,咱們須要手動觸發事件code

//IE之外
elem.dispatchEvent(type);
//觸發button的click事件
button.dispatchEvent('click');

//IE 
elem.fireEvent(type);
//觸發button的click事件
button.fireEvent('onclick');

事件對象和事件源

當調用事件處理函數時候,會隱形的傳入一個對象,這個對象就含有了事件的一些狀態和信息對象

function handler(e){
    //獲取事件對象 
    // IE的低版本,事件對象不是經過event傳入的,而是放在window對象上面
    e = event || window.event;
    //獲取事件源 
    //IE下是 srcElement
    var target = e.target || e.srcElement;
    
}

取消默認行爲

常規的點擊連接會打開,可是有時候只是但願處理自定義的業務邏輯而不是打開,這時咱們應該取消默認行爲。

function eventHandler(e) { 
    e = e || window.event; 
    // 防止默認行爲 
    if (e.preventDefault) { 
        e.preventDefault();//IE之外 
    } else { 
        e.returnValue = false;//IE 
    //注意:這個地方是沒法用return false代替的 
   } 
}

阻止事件傳播

有時咱們須要阻止事件冒泡

function handler(e){
    e = e || window.event;
    if(e.stopPropagation){
        e.stopPropagation();//IE之外
    }else{
        e.cancelBubble = true;//IE
    }
}

事件代理

ul下有多個li,咱們想要實如今點擊每一個li的時候,都觸發click事件,若是在每一個li上都綁定click事件,工做量將會很大,且要維護多個函數,性能也比較差。這種狀況下,咱們應該使用事件代理

//在ul上綁定事件,點擊li時,經過冒泡傳遞到ul上,觸發click事件
ul.addEventListener('click',handler,false);

function handler(e){
    e = e || window.event;
    var targetNode = e.target || e.srcElement;
    //判斷點擊的target子元素的類型來觸發相應的事件
    if(targetNode.nodeName.toLowerCase() === 'li'){
        // dosomething
    }
}

事件相關的知識點仍是比較清晰的,實際使用時,善用事件代理哦!

相關文章
相關標籤/搜索