自定义跨浏览器的事件处理程序

为了以跨浏览器的方式处理事件,不少开发人员会使用能够隔离浏览器差异的javascript库,本文从事件处理程序、事件对象差异出发,演示开发最适合的事件处理方法
 
 

基本名词解析:
事件
用户或浏览器自身执行的某种动作
事件流
从页面中接收事件的顺序,,IE的事件流指的是事件冒泡流,而Netscape Communicator的事件流是事件捕获流
事件冒泡
事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)
事件捕获
不太具体的节点应该更早接收到事件,而最集体的节点应该最后接收到事件
事件处理程序
响应某个事件处理的函数(或事件侦听器)
 
事件流包括的三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段
  自定义跨浏览器的事件处理程序
事件处理程序
 
事件处理程序名称
说明
添加事件
删除事件
DOM0级
将一个函数赋值给一个事件处理程序属性。
//使用javascript指定事件处理程序,首先必须取得一个要操作的对象应用
 var btn = document.getElementById("myBtn");
        btn.onclick = function(){
            alert(this.id);
        };
     
  
        var removeBtn = document.getElementById("myRemoveBtn");
        removeBtn.onclick = function(){
            btn.onclick = null;
        };
DOM2级
用于处理指定和删除事件处理程序操作的方法:addEventListener()和removeEventListener(),接受3个函数:处理的事件名,作为事件处理程序的函数和一个布尔值(true捕获阶段,false冒泡阶段)
var btn = document.getElementById("myBtn");
        var handler = function(){
            alert(this.id);
        };
        btn.addEventListener("click", handler, false); 
 var removeBtn = document.getElementById("myRemoveBtn");
        removeBtn.onclick = function(){
            btn.removeEventListener("click", handler, false); //大多数情况下,将事件处理函数添加到事件流的冒泡阶段,这样最大限度兼容各种浏览器
        };
IE事件处理程序
实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。接受两个参数:事件处理程序名称与事件处理程序函数
var btn = document.getElementById("myBtn");
        var handler = function(){
            alert("Clicked");
        };
        btn.attachEvent("onclick", handler);
       
       
 var removeBtn = document.getElementById("myRemoveBtn");
        removeBtn.onclick = function(){
            btn.detachEvent("onclick", handler);
        };
 
另外还有一种HTML事件处理程序,不推荐使用。
<input type="button" value="Click Me" onclick="alert(&quot;Clicked&quot;)" />
    <script type="text/javascript">
        function showMessage(){
            alert("Hello world!");
        }
    </script>
因为它存在如下缺点:
1,不同javascript引擎遵循的标识符解析规则略有差异,很有可能会在访问非限定对象成员时出错。
2,HTML和javascript代码紧密耦合,如果要更换事件处理程序需要改动HTML和javascript代码
 
 


var EventUtil = {

 

/*

    参数说明:

            element:要操作的对象

            type:事件名称

            handler:事件处理程序函数

*/

    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;

        }

    }

};

 

 
使用演示
var btn = document.getElementById("myBtn");

        var handler = function(){

            alert("Clicked");

        };

        EventUtil.addHandler(btn, "click", handler);

       

        var removeBtn = document.getElementById("myRemoveBtn");

        EventUtil.addHandler(removeBtn, "click", function(){

            EventUtil.removeHandler(btn, "click", handler);

        });

 

 
 
事件对象
 
在触发DOM上的某个事件是,会产生一个世家对象event,这个对象中包含所有与事件有关的信息。
包括导致事件的元素(DOM中event.currentTarget,event.target,this;IE中window.event.srcElement或event.srcElement,this),事件类型(event.type)和其他与事件相关的信息
 
我们经常使用event.preventDefault()取消其默认行为。另外,stopProgation()方法用于立即停在事件在DOM层次中的传播,即取消进一步的事件捕获或冒泡
 
需要通过一个函数处理多个事件,可以使用type属性
var btn = document.getElementById("myBtn");

        var handler = function(event){

            switch(event.type){

                case "click":

                    alert("Clicked");

                    break;

                   

                case "mouseover":

                    event.target.style.backgroundColor = "red";

                    break;

                   

                case "mouseout":

                    event.target.style.backgroundColor = "";

                    break;

            }

        };

       

        btn.onclick = handler;

        btn.onmouseover = handler;

        btn.onmouseout = handler;

 

虽然DOM和IE中的event对象不同,但基于它们之间的相似性依旧可以拿出跨浏览器的方案。
 
var EventUtil = {

    /*

    功能说明:绑定事件

    参数说明:

            element:要操作的对象

            type:事件名称

            handler:事件处理程序函数

    */

    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;

        }

    },

    

/*

            函数说明:鼠标按钮。

                主鼠标按钮被单击时触发click事件

                DOM的button属性:

                    0:主鼠标按钮

                    1:中间鼠标(滚轮)

                    2:次鼠标按钮

                但对于IE8及之前版本button属性很大差异

    */

    getButton: function(event){

        if (document.implementation.hasFeature("MouseEvents", "2.0")){

            return event.button;

        } else {

            switch(event.button){

                case 0:

                case 1:

                case 3:

                case 5:

                case 7:

                    return 0;

                case 2:

                case 6:

                    return 2;

                case 4: return 1;

            }

        }

    },

    

/*

        函数说明:键盘与文本事件

            IE8及其他版本和Opere是keyCode中保存字符

            其他主流浏览器支持一个char Code属性,发生在keypress事件

    */

    getCharCode: function(event){

        if (typeof event.charCode == "number"){

            return event.charCode;

        } else {

            return event.keyCode;

        }

    },

    

    getClipboardText: function(event){

        var clipboardData = (event.clipboardData || window.clipboardData);

        return clipboardData.getData("text");

    },

    

    getEvent: function(event){

        return event ? event : window.event;

    },

    

    getRelatedTarget: function(event){

        if (event.relatedTarget){

            return event.relatedTarget;

        } else if (event.toElement){

            return event.toElement;

        } else if (event.fromElement){

            return event.fromElement;

        } else {

            return null;

        }

    

    },

    

    getTarget: function(event){

        return event.target || event.srcElement;

    },

    

/*

            函数说明:鼠标滚轮事件



    */

    getWheelDelta: function(event){

        if (event.wheelDelta){

            return (client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta);

        } else {

            return -event.detail * 40;

        }

    },

    

/*

        函数说明:取消其默认行为

    */

    preventDefault: function(event){

        if (event.preventDefault){

            event.preventDefault();

        } else {

            event.returnValue = false;

        }

    },

    /*

        函数说明:解绑事件

    */

    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;

        }

    },

    

    setClipboardText: function(event, value){

        if (event.clipboardData){

            event.clipboardData.setData("text/plain", value);

        } else if (window.clipboardData){

            window.clipboardData.setData("text", value);

        }

    },

    

/*

        函数说明:立即停在事件的传播,即取消进一步的事件捕获或冒泡

    */

    stopPropagation: function(event){

        if (event.stopPropagation){

            event.stopPropagation();

        } else {

            event.cancelBubble = true;

        }

    }



};

 

 
 
 
 

你可能感兴趣的:(浏览器)