前端面試回顧(3)---事件綁定及相關兼容性問題

面試中常會問到的一個問題,事件委託,我以爲除了可以看你對dom2事件的瞭解程度外,對瀏覽器的兼容也是有必定考察的。面試

考察到的點主要在addEventListener(),attachEvent(),事件對象等。
常見的考察方式是問你如何在一個列表中,點擊某個li,就彈出被點擊li的索引,或者讓你實現相似JQuery的on和off這兩個方法瀏覽器

簡單來作,就能夠給全部的li添加dom0級的事件,每一個li都綁定一個onclick事件:dom

window.onload = function(){
    //dom0級的方式,直接爲每一個li綁定事件
    var ul = document.getElementById("ul");
    var lis = ul.querySelectorAll('li');
    for(var i = 0;i < lis.length;i++){
        (function(j){
            lis[j].onclick = function(e){
                alert(j+1);
            }
        })(i);
    }
}

這種方式很簡單,但缺點也很明顯,其實能夠利用事件冒泡,把事件綁定在li的父級ul上,在點擊以後,就會被ul的事件處理程序捕獲到,從而處理。
這裏要注意的就是兼容問題了,addEventListener並不被IE9如下的瀏覽器支持,與之對應的是attachEvent方法。並且,事件對象在標準和IE瀏覽器中也有不一樣。code

window.onload = function(){
    var ul = document.getElementById("ul");
    if(ul.addEventListener){
        ul.addEventListener("click",handler);
    }else if(ul.attachEvent){
        ul.attachEvent("onclick",handler);
    }

    function handler(e){
        var ul = document.getElementById("ul");
        var e = e || window.event;                //事件對象兼容
        var liList = ul.getElementsByTagName("li");
        for(var i = 0;i<liList.length;i++){
            var target = e.target || e.srcElement;//事件對象屬性的不一樣
            if(target == liList[i]){
                alert(i+1);
            }
        }
    }
}

上面的代碼中就判斷了瀏覽器支持的狀況,從而去適配標準瀏覽器和IE瀏覽器。對象

若是是然你實現相似JQuery的on方法和off方法,能夠參考下面啊的代碼,這裏統一參考js高程中的寫法,定義一個EventUtil對象,來放這些方法。索引

var EventUtil = {
    addHandler : function(element, type, handler){
        if(element.addEventListener){
            element.addEventListener(type,handler,false);
        }else if(element.attachEvent){
            element.attachEvent("on" + type, handler);
        }else{
            element["on" + type] = handler;
        }
    },
    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和IE中的事件對象仍是有很大不一樣的。
經常使用的幾個如preventDefault(),stopPropagation(),target等,IE下均有不一樣的表示。見下事件

功能 標準瀏覽器相關屬性 IE相關屬性
事件的目標 target srcElement
取消事件默認行爲 preventDefault() returnValue
取消事件冒泡 stopPropagation() cancelBubble

剩下的就是利用這幾個屬性,擴展一下EventUtil對象,來作兼容了。element

var EventUtil = {
    getEvent : function(event){
        return event ? event : window.event;
    },
    getTarget : function(event){
        return event.target || event.srcElement;
    },
    preventDefault : function(event){
        if(event.preventDefault){
            event.preventDefault();
        }else{
            event.returnValue = false;
        }
    },
    stopPropagation : function(event){
        if(event.stopPropagation){
            event.stopPropagation();
        }else{
            event.cancelBubble = true;
        }
    }
}
相關文章
相關標籤/搜索