2

1.事件流

事件流描述的是从页面中接收事件的顺序。

1.1 事件冒泡

IE中的事件流叫做冒泡,即时间最开始由最具体的元素接收,然后逐级向上传播到较为不具体的节点,直到传播到document对象。
例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Event Exampple</title>
</head>
<body>
    <div id="myDiv">click</div>
</body>
</html>

如果单击页面中div元素,那么click时间会按照以下顺序发生:

  1. <div>

  2. <body>

  3. <html>

  4. document

图解事件冒泡过程:
图片描述

1.2 事件捕获

事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。

以上面html页面为例,如果单击页面中div元素,那么click时间会按照以下顺序发生:

  1. document

  2. <html>

  3. <body>

  4. <div>
    图解事件捕获过程:

图片描述

1.3 DOM事件流

"DOM2级事件流"规定的事件包括三个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段。
以上面html页面为例,单击div元素会按照以下顺序触发事件:
图片描述

2.事件处理程序

以下是一个跨浏览器的事件处理程序

var eventUtil = {  
        // 添加事件处理程序 
        addHandler: function(element, type, handler) {  
            if (element.addEventListener) {  
                element.addEventListener(type, handler, false);  //DOM
            } else if (element.attachEvent) {  
                element.attachEvent('on' + type, handler);  //IE
            } else {  
                element['on' + type] = handler;  
            }  
        },  
        // 移除事件处理程序(通过addEventListener添加的匿名函数无法移除)  
        removeHandler: function(element, type, handler) {  
            if (element.removeEventListener) {  
                element.removeEventListener(type, handler, false);  //DOM
            } else if (element.detachEvent) {  
                element.detachEvent('on' + type, handler);  //IE
            } else {  
                element['on' + type] = null;  
            }  
        },  
        //获取事件  
        getEvent: function(event) {  
            return event ? event : window.event;  
        },  
        //获取事件类型  
        getType: function(event) {  
            return event.type;  
        },  
        //获取事件源  
        getElement: function(event) {  
            return event.target || event.srcElement;  
        },  
        //阻止默认事件比如a链接跳转  
        preventDefault: function(event) {  
            if (event.preventDefault) {  
                event.preventDefault();  
            } else {  
                event.returnValue = false;  
            }  
        },  
        //阻止事件冒泡  
        stopPropagation: function(event) {  
            if (event.stopPropagation) {  
                event.stopPropagation();  
            } else {  
                event.cancelBubble = true;  
            }  
        }  
    }  

3.事件委托

3.1什么是事件委托?

事件委托是利用事件冒泡原理,指定一个事件处理程序,就可以管理某一类型的所有事件。

3.2为什么要事件委托?

添加在页面上的事件处理程序的数量直接关系到页面的整体运行性能,首先,事件处理函数都是对象,其数量越多,占用内存就越大,则性能就越差。其次,必须事先指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。

3.3例解事件委托

//html

<ul id="myLinks">
        <li id="goSomewhere">Go somewhere</li>
        <li id="doSomething">Do something</li>
        <li id="sayHi">Say hi</li>
</ul>

//传统添加事件方法

<script type="text/javascript">
    var item1 = document.getElementById("goSomewhere");
    var item2 = document.getElementById("doSomething");
    var item3 = document.getElementById("sayHi");

    EventUtil.addHandler(item1,"click",function(event){
        location.href = "http://www.baidu.com";
    });
    EventUtil.addHandler(item2,"click",function(event){
        document.title = "changed the dicument's title";
    });
    EventUtil.addHandler(item3,"click",function(event){
        alert("hi");
    });
</script>

//事件委托方法
<script type="text/javascript">
    var list = document.getElementById("myLinks");

    EventUtil.addHandler(item1,"click",function(event){
        event = EventUtil.getEvent(event);
        var target = EventUtil.getTarget(event);
        switch(target.id){
            case "goSomewhere":
                document.title = "changed the dicument's title";
                break;
            case "doSomething":
                location.href = "http://www.baidu.com";
                break;
            case "sayHi":
                alert("hi");
                break;
        }
    });

时间委托相比传统添加事件监听的优点:

  • 在页面中设置事件处理程序所需的时间更少,只添加一个时间处理程序所需的DOM引用次数更少,所花的时间更少。

  • 整个页面占用的内存空间更少,能够提升整体性能。


Evan_Chen
130 声望5 粉丝