JavaScript高级程序设计(反刍) 12

第13章:

事件流就是从页面接收事件的顺序。IE采用的是冒泡流,也就是从该元素依次向上响应事件,而Netscape采用的是事件捕获流,也就是从上向下响应事件。
事件

DOM2中规定事件流包含三个阶段:
1.事件捕获阶段
2.处于目标阶段
3.事件冒泡阶段
事件流

事件处理程序
事件就是用户或者浏览器自身执行的某种动作,而响应某个事件的函数叫做事件处理程序。所有的事件处理程序都是以on开头。
HTMl事件处理程序:
直接在其HTML文档中写入οnclick=”代码/函数名”即可
在事件处理程序中,都存在一个叫做event的变量,这个变量可以直接访问事件对象。
(一般不推荐使用HTML事件处理程序的写法,因为这种写法让HTML文档与JavaScript脚本耦合度太高)

DOM0级事件处理程序:
在脚本中使用DOM方法直接获得该元素,写出元素.onclick = function(){~}即可

DOM2级事件处理程序:
DOM2级事件定义了两个方法:
addEventListener()方法,为元素添加事件处理
removeEventListener()方法,删除元素身上的事件处理

两种方法都接收三个参数:要处理的事件名、作为事件处理程序的函数、一个布尔值。最后的这个布尔值表示的是哪种处理方式,true就是捕获阶段调用事件处理,false就是冒泡阶段调用事件处理,一般都为false。

这里需要注意,使用addEventListener()方法添加的事件,只能通过removeEventListener来删除,删除时必须前后的参数保持一致。尤其是当前面添加时使用匿名函数的情况,必须将这个匿名函数单拉出来,绝对不能直接一样,那样无法删除。

var btn = document.getElementById(“myBtn”);
btn.addEventeListener(“click”, function (){
    alter(this.id);
}, false);
btn.removeEventeListener(“click”, function (){        //删不掉
    alter(this.id);             
}, false);

var btn1 = document.getElementById(“myBtn”);
var fnc = function (){
    alter(this.id);
};
btn1.addEventeListener(“click”, fnc, false);
btn1.removeEventeListener(“click”, fnc, false);      //可以删除

(这里需要注意,大多数的情况下都是将处理程序添加到事件流的冒泡阶段,而非捕获阶段)

IE的事件处理程序:
attachEvent():添加事件处理程序
detachEvent():删除事件处理程序
两种方法的参数都是:事件处理程序名称、事件处理程序函数,并且只支持将事件添加到冒泡阶段

跨浏览器的写法:

var EventUtil = {
    addHandler: function(element, type, handler){
    if(element.addEventListener){
   		element.addEventListener(element, type, 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] = handler;
		}
	}
}

(添加方法/删除方法时,直接调用addHandler()方法/removeHandler()方法即可,传入三个参数:要执行方法的元素、方法类型、函数)

事件类型:
1.UI事件(user interface),当用户与页面上的元素交互时触发
2.焦点事件,当元素获得/失去焦点触发
3.鼠标事件,用户通过鼠标执行操作触发
4.滚轮事件,使用鼠标滚轮时触发
5.文本事件,输入文本时触发
6.键盘事件,使用键盘执行操作时触发
7.合成事件,
8.变动事件

UI事件:

  1. load:当页面完全加载后在window上触发,主要的作用是判断页面是否加载完成,该方法也可以被用在其他元素上
  2. unload:当页面完全卸载后在window上触发,只要用户从一个页面切换到另一个页面,之前的页面就会触发unload,主要作用是清除引用,避免内存泄漏
  3. error:当页面发生JavaScript错误时触发
  4. resize:当页面的大小发生变化时触发,页面最大化和最小化也会触发,但是在不同的浏览器中触发的规则不同,所以尽可能少用
  5. scroll:当用户滚动带滚动条的内容时,在元素上触发

(这里需要注意:新的图像元素不一定要从添加入文档后才开始下载,只要设置了src属性就开始下载;但是JavaScript脚本是必须在加入文档后才开始下载的)

焦点事件:
Blur事件:元素失去焦点时触发,事件不冒泡
Focus事件:在元素获得焦点时触发,事件不冒泡

鼠标与滚轮事件:
click:单击/按下回车键触发
dbclick:双击触发
mousedown:在用户按下任意鼠标键时触发
mouseenter:鼠标首次从元素外部移入元素时触发,事件不冒泡,但移入元素的后代元素不触发
mouseleave:位于元素内的光标移出元素时触发,事件不冒泡
mousemove:当鼠标指针在元素内部移动时重复触发
mouseout:当鼠标从元素内部移出时触发
mouseover:当鼠标从元素外部移入元素内时触发

mousewheel事件:滚轮事件,当滑动鼠标的滚轮/笔记本触控板时触发
1.客户区坐标位置
客户区
2.页面坐标位置
(不翻页的情况下clientX / clientY与pageX / pageY相同,翻页的情况下,clientX / clientY获取的是在当前页面中的坐标位置,但是pageX / pageY获取的是从最上面到当前页面的位置)
页面坐标
3.屏幕坐标位置:
屏幕坐标
4.修改键
修改键就是shift、ctrl、alt、meta,这四种按键可以改变要采取的操作,对应的状态就是shiftKey、ctrlKey、altKey、metaKey

5.相关元素
相关元素就是指的鼠标事件触发时元素的主从关系

6.鼠标按钮
鼠标按钮一般有三个,左键右键和中间滑轮按键,DOM中的button属性:0表示左键,1表示中间键、2表示右键.在IE中不太一样,所以需要一种兼容写法

7.更多的事件信息:
Detail:表示在一个给定的位置发生了多少次单击,每mousedown和mouseup触发一次计数加1

8.鼠标滚轮事件
各种浏览器支持的事件属性不一样,DOM的普遍属性胃wheelDelta属性,每滚动一次都是120的倍数,firefox支持的是detail属性,每滚动一次都是3的倍数。
(这里大多数的情况下都是判断鼠标滚轮向前还是向后滑,只需要判断正负即可,不判断数值)

键盘与文本事件:
DOM3级键盘事件:
Keydown:用户按下任意键触发
Keypress:用户按下字符键触发
Keyup:用户释放键时触发

在发生keydown和keyup事件的时候,会触发一个keyCode属性,该属性包含一个代码。就是键对应的值代码
键值1
键值2

( 中间很大一部分个人感觉没啥用,也没怎么看懂,所以略掉了,有兴趣的同学可以去看看原书的P382~P402 )

事件委托:
多次调用事件处理程序情况下一般容易造成浏览器响应速度慢,所以发明了事件委托的写法,利用了事件处理程序冒泡的特性,将多个事件在其最顶层进行事件响应,而非单个事件响应。
原始写法
事件委托
移除事件处理程序:
使用前面的removeHandler的方法进行移除只能将其在文档中卸载掉,但是并未真正被内存回收,所以在事件处理程序结束使用的时候,最好将其置为null

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" + typpe] = handler;
        }
    },
    getEvent: function(event){                                 //获得event
        return event?event:window.event;
    },
    getTarget: function(event){                               //获得事件目标
        return event.target || event.srcElement;
    },
    getRelatedTarget: function(event){                        //获得相关元素
        if(event.relatedTarget){
            return event.relatedTarget;
        }else if(event.toElemnt){
            return event.toElemnt;
        }else if(event.fromElement){
            return event.fromElement;
        }else{
            return null;
        }
    },
    getButton: function(event){                              //鼠标事件
        if(document.implementation.hasFeature("MouseEvent", "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;
            }
        }
    },
    getWheelDelta: function(event){                         //滑轮事件
        if(event.wheelDelta){
            return (client.engine.opera && client.engine.opera<9.5 ? -event.wheelDelta: event.wheelDelta);
        }else{
            return -event.detail * 40;
        }
    },
    getCharCode: function(event){                           //获得键码
        if(typeof event.charCode == "number"){
            return event.charCode;
        }else{
            return event.keyCode;
        }
    },
    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;
        }
    },
    stopPropagation: function(event){
        if(event.stopPropagation){
            event.stopPropagation();
        }else{
            event.cancelBubble = true;
        }
    }
};

猜你喜欢

转载自blog.csdn.net/Feng_ye__/article/details/90055401