第13章、事件

13.1 事件流

“DOM2级事件”规定事件流包括3个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段。
事件捕获表示从最外层节点开始捕获事件,然后逐级像内传播直到具体节点。
事件冒泡表示事件由最具体元素开始接受元素,然后逐级向上传播到文档节点。


13.2 事件处理程序

13.2.1 DOM2级事件处理程序

“DOM2级事件”为所有DOM节点定义了addEventListener()和removeEventListener()两个方法,分别用于指定事件处理程序和移除事件处理程序。都接收3个参数:事件名称、事件处理程序、一个布尔值,布尔值为true,则在捕获阶段调用事件处理程序,布尔值为false,则在冒泡阶段调用事件处理程序。
使用DOM2级事件处理程序可以为同一个事件添加多个程序,会按照添加的顺序触发。addEventListener()添加的事件处理程序只能用removeEventListener()来移除,移除时传入的参数与添加时的相同,无法删除匿名函数,因为两个一样的匿名函数并不是同一个函数。

13.2.2 IE事件处理程序

IE使用attachEvent()和detachEvent(),都接收两个参数,事件名称和事件处理程序,只在冒泡阶段触发。事件名称需要添加“on”前缀,同一事件多个程序会按添加的相反顺序触发。


13.3 事件对象

在DOM上触发事件时,会产生一个event事件对象。这个对象中包含着所有与事件有关的信息。

13.3.1 DOM中的事件对象

兼容DOM的浏览器会将一个event对象传入事件处理程序中,event对象所有属性:
bubble,布尔值,只读,表示事件是否冒泡;
cancelable,布尔值,只读,表示是否可以取消事件默认行为;
currentTarget,节点,只读,当前正在处理时间的元素,在事件处理程序内部总是等于this值;
defaultPrevented,布尔值,只读,为true表示已经调用了preventDefault()方法;
detail,数值信息,只读,事件相关细节信息;
eventPhase,数值信息,只读,表示调用事件处理程序的阶段,1表示捕获,2表示“处于目标”,3表示冒泡;
preventDefault(),方法,取消事件的默认行为,cancelable为true时才可以使用;
stopImmediatePropagation(),方法,取消事件进一步冒泡,同时阻止任何事件处理程序被调用;
stopPropagation(),方法,取消事件的进一步冒泡,bubble为true时才可以使用;
target,节点,事件的实际目标;
trusted,布尔值,只读,为true表示事件是由浏览器生成的,为false表示事件由JavaScript添加;
type,字符串,触发的事件类型;
view,事件发生的window对象。

13.3.2 IE中的事件对象

使用DOM0级添加事件处理程序时,event对象是window的一个属性,使用attachEvent()时,event可以通过window对象访问,也会作为参数传入事件处理程序。IE事件对象属性:
cancelBubble,布尔值,默认为false,设置为true就可以取消事件冒泡;
returnValue,布尔值,默认为true,设置为false可以取消事件默认行为;
srcElement,节点,事件的实际目标;
type,字符串,事件的名称。

13.3.3 跨浏览器的事件模型
var EventUtil = {
    // 添加事件
    addHandler: function (ele, type, handler) {
        if(ele.addEventListener){
            ele.addEventListener(type,handler,false);
        }else if(ele.attachEvent){
            ele.attachEvent("on"+type,handler);
        }else{
            ele["on"+type] = handler;
        }
    },
    // 移除事件
    removeHandler: function (ele, type, handler) {
        if(ele.removeEventListener){
            ele.removeEventListener(type,handler,false);
        }else if(ele.detachEvent){
            ele.detachEvent("on"+type,handler);
        }else{
            ele["on"+type] = null;
        }
    },
    // 获取事件对象
    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;
        }
    },
    // 获取mouseover和mouseout事件触发时的相关元素
    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;
        }
    },
    // 获取mousedown和mouseup事件触发时的按键信息
    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;
            }
        }
    },
    // 获取mousewheel事件(firefox下为DOMMouseScroll事件)鼠标滚轮增量值
    getWheelDelta:function (event) {
        if(event.wheelDelta){
            return event.wheelDelta;
        }else {
            return -event.detail * 40;
        }
    },
    // 获取键盘事件中按键的字符编码
    getCharCode:function (event) {
        if(typeof event.charCode === "number"){
            return event.charCode;
        }else{
            return event.keyCode;
        }
    },
    // 获取剪贴板中的数据
    getClipboardText:function (event) {
        var clip = (event.clipboardData || window.clipboardData);
        return clip.getData("text");
    },
    // 设置剪贴板中的数据
    setClipboardText:function (event,value) {
        if(event.clipboardData){
            return event.clipboardData.setData("text/plain",value);
        }else if(window.clipboardData){
            return window.clipboardData.setData("text",value);
        }
    }
};

13.4 事件类型

13.4.1 UI事件

load事件,当页面完全加载后(包括所有图像,JavaScript文件,CSS文件等外部资源),就会在window上面触发该事件。
图像上面也可以触发load事件,当图像加载完毕时就会触发绑定在img图像上的load事件,在新建图像元素时(无论是DOM创建img标签还是创建新的Image对象),只要设置了src属性,图像就会开始下载。为保证能触发事件,要先绑定事件,再为图像设置src属性。

你可能感兴趣的:(第13章、事件)