JS高级程序设计学习笔记之JS事件(1)
-
事件流
-
冒泡
定义:事件开始时由最具体的元素接收,然后逐级上传到较为不具体的节点。(IE9、FF、Chrome、Safari会将事件一直冒泡到window对象。IE5.5及其以下会跳过<html>元素,直接从body跳到document)。若发生事件的节点元素并没有绑定该事件,则这个动作会向上冒泡,直到被执行,一直冒泡到window对象。
阻止冒泡:①使用stoppropagation()
②在函数中进行一次判断,if(event.target==event.current.target){function(){……}}
-
捕获
定义:不太具体的节点先接收到事件,而具体的节点之后接收到事件。(老版浏览器不支持事件捕获。IE9、FF、Chrome、Opera、Safari均支持事件捕获,且从window开始捕获)
- 事件流:事件流分为三个阶段。即,捕获阶段,处于目标阶段,冒泡阶段。(DOM2级事件规范要求捕获阶段不涉及事件目标,但是IE9、FF、Chrome、Opera9.5、Safari都会在捕获阶段接触发生在事件对象上的事件,结果即是有两个机会在目标对象上面操作事件。IE8以及更早版本不支持DOM事件流)
-
-
事件处理程序:
-
HTML事件处理程序:
- 嵌入到行间中
- 可以实现具体的动作,如alert等。也可以用来调用其他函数。
- 代码在运行时,有权访问全局作用域中的所有变量。
- 可以像访问局部变量一样访问document以及该元素本身的成员。(P349)若为表单输入元素,作用域中还会包含表单元素入口,即无需引用表单元素就能访问其他表单内容。
- 问题:时差,耦合
-
DOM0级事件处理程序:
- 将一个函数赋值给一个事件处理程序属性。如btn.onclick = function(){….}。所有浏览器均支持此方法。
- 在函数的作用域中运行。This引用当前元素。
- 以此方法添加的事件处理程序会在事件流的冒泡阶段被处理。
- 删除:btn.onclick = null
-
DOM2级事件处理程序:
- 指定/删除事件处理程序:addEventListener() / removeEventListener(),参数为a、要处理的事件名(没有on)b、作为事件处理程序的函数c、布尔值(true:捕获时调用,false冒泡时调用)在元素作用域中运行。
- 可以添加多个事件处理程序。删除时需参数完全相同,即匿名函数无法删除。
- IE8以下不兼容。
-
IE事件处理程序
- attachEvent() / detachEvent(),参数为a、事件处理名称(有on)b、事件处理函数
- 该方法将添加事件至冒泡阶段。可添加多个事件处理程序。只有IE/Opera兼容
- 在全局作用域中运行,this = window。
- 事件不以添加顺序运行,以相反顺序触发
-
5、跨浏览器的事件处理程序 P353。两段兼容性代码见书。
三、事件对象:在触发DOM上的某事件时,会产生一个事件对象event,这个对象中包含着所有与事件相关的信息。
1、DOM中的事件对象:兼容DOM的浏览器会将一个event对象传入到事件处理程序中。(不需要一定将event写在function的参数里)。在HTML事件处理程序中,变量event储存着event对象。
- currenTarget,事件处理程序当前正在处理事件的那个元素 =this。即事件注册到的那个元素。
- target,事件的目标。比如,鼠标点击哪个元素,则target就指向该元素。
- type,事件类型
- preventDefault(),阻止事件的默认行为。前提需设置cancelable为true。
- stopProgation(),停止捕获和冒泡。
2、IE中的事件对象:
- 使用attachEvent,event作为参数传入事件处理程序,也可以通过window访问。(Edge不支持attachEvent)
- 在使用DOM0方法添加事件处理程序时。Event对象作为window对象的一个属性存在。Var event =window.event。(经测试,在DOM0方法中,不将event当做参数传入,也不将他定义为变量,直接比较event与window.event,二者完全相同。Chrome下)。
- HTML事件处理程序,通过一个名为event的变量访问event。
- 注意,因为事件处理程序的作用域是根据指定他的方法决定的,所以不能认为this会始终等于事件目标。使用event.srcElement比较保险,与DOM中的target相同。
- returnValue=preventDefault cancelBubble(只能取消冒泡)=stopPropagation
- 跨浏览器的事件对象P360