第一次在segmentfault写文章,希望通过这种方式来巩固所学的知识,也欢迎童鞋们指正其中有不对和错误的地方。^+^
事件流:页面中接收事件的顺序,即当一个事件发生时,该事件的传播过程便叫做事件流
事件流的种类
事件冒泡
事件由最具体的元素开始逐级向上传播至较为不具体的节点(文档)
|
|
当我们点击id为box的div时,该点击事件传播顺序如下
div –> body –> html –>document
特别说明:IE5.5及更早的版本将绕过html节点直接到document,IE9,Firefox,chrome和safari将冒泡到window对象
事件捕获
事件捕获和事件冒泡似乎截然相反,由不太具体的节点先接收到事件 –>再到最具体的节点。同样还是用上面冒泡例子,则事件的传播顺序则是:
document –> html –>body –>div
特别说明:ie8之前不支持事件捕获,IE9,safari,chrome,opera,firefox目前支持良好。并且这些浏览器不是从document开始捕获,而是从window对象开始。
DOM事件流阶段
- 捕获阶段
- 目标阶段
- 冒泡阶段
以上面的代码为例子,由图可以很清晰地看出首先发生的是事件捕获–>实际的目标接收事件–>事件冒泡
特别说明:在DOM事件流中,实际的目标不会在捕获阶段接收到事件,即捕获阶段到body就停止,”下一阶段”是目标阶段,该阶段可以看成是事件冒泡的一部分,最终事件又被传播会document。
BUT :我们的各大浏览器总是不喜欢按照规范来,IE9,Safari,chrome,firefox及其更高的版本中都会在捕获阶段出发事件对象上的事件,最后导致有两个机会在目标对象上操作事件。
- ##事件处理程序
事件:用户或者浏览器自身执行的某个动作,比如load,click,mousemove等
事件处理程序:相应某个事件的函数叫做事件处理函数(也叫做事件侦听器)事件处理程序类别
1 html事件处理程序:某个元素支持的某个事件可以用与事件处理程序同名的html特性来指定,该特性的值是能够执行的javascript代码。12345<input type="button" value="点击" onclick="alert('我被点击了')" />/*当点击该按钮的时候,浏览器会弹出'我被点击了';*/
当然也可以给onclick赋值页面中其他地方定义的脚本
优点:简单明了,省去获取元素等一系列前提操作
缺点:html代码与js代码高度耦合,不符合分离原则
2 DOM0级别事件处理函数:使用 element.on[eventname]=fn的方式给元素添加事件
3 DOM2级事件处理程序:DOM2级添加了addEventListener(添加事件处理程序)和removeEventListener(移除事件处理程序)
添加事件处理函数
移除事件处理函数:如果事件处理函数是有名函数,则可以通过名字来移除,匿名函数无法移除。
4IE事件处理程序:ie实现了与dom类似的两个方法,attachEvent(添加),detachEvent(删除)
添加事件处理函数
删除事件处理函数
事件函数封装
绑定 为了解决attachEvent的this指向问题,并且可以通过有名称的函数来解除事件绑定,现在处理如下
解除
使用方式
|
|
事件对象
当触发DOM上面的某个事件的时候,会产生一个事件对象event,这个对象中包含着所有与事件对象有关的信息。例如该事件类型,导致事件的元素等
DOM中的事件对象
DOM中的事件对象:兼容DOM的浏览器会将event对象传入到事件处理程序中,无论指定事件处理程序用什么方式(html方式,DOM0级方式,DOM2级方式)
|
|
总的来说event对象包含与创建他的特定事件有关的属性和方法,但是触发的事件类型不同,则可用的属性和方法也不一样。但是都会包含以下成员
属性/方法 | 类型 | 读/写 | 说明 | |
---|---|---|---|---|
currentTarget | element | 只读 | 事件处理程序当前正在处理程序的那个元素,我的理解是事件的直接绑定者 | |
target | element | 只读 | 事件的目标 | |
cancelable | boolean | 只读 | 表示是否可以取消事件的默认行为 | |
preventDefault() | function | 只读 | 取消事件的默认行为 ,前提是cancelable为true | |
bubbles | boolean | 只读 | 表明事件是否可以冒泡 | |
stopPropagation() | function | 只读 | 取消事件的进一步冒泡或者捕获,前提是bubbles为true | |
type | boolean | 只读 | 事件类型 | |
view | abstractView | 只读 | 与事件关联的抽象视图,等同于发生事件的window对象 | |
detail | integer | 只读 | 与事件相关的细节信息 | |
eventPhase | integer | 只读 | 调用事件处理程序的阶段,1::捕获,2:“处于目标”,3:冒泡 | |
trusted | boolean | 只读 | 为true表示事件是由浏览器生成的,为false表示事件是由开发人员通过js生成的。(DOM3) | |
stopImmediatePropagation() | function | 只读 | 取消事件的进一步捕获或者冒泡,同时阻止任何事件处理程序被调用(DOM3) |
特别说明:只有在事件处理程序被执行的期间,event对象才会存在,一旦事件处理程序执行完成,其就会被销毁。
IE中的事件对象
与访问DOM中的事件对象不同,要访问IE中的event对象有几种不同的方式。取决于指定事件处理程序的方法。
- html event
- 函数参数
- window.event
同样IE中的event对象也包含着与创建他的事件相关的属性和方法,其中很多的属性和方法都有对应的或者是相关的DOM属性和方法。当然也会事件的不同,其属性和方法也会有所不同,但是都会包含下表内容
属性/方法 | 类型 | 读/写 | 说明 | |
---|---|---|---|---|
srcElement | element | 只读 | 事件的目标(与DOM中的target属性相同) | |
type | string | 只读 | 事件的类型 | |
cancelBubble | boolean | 只读 | 默认为false,设置为true表示取消冒泡(与stopPropagation()作用相同) | |
returnValue | boolean | 只读 | 默认为true,设置为false就可以取消默认行为(与preventDefault()作用相同) |
跨浏览器事件对象封装
我们为eventUtil添加几个方法,以此来达到有关event对象的常用的跨浏览器的使用目标
- getEvent() 获取事件对象
- getTarget()获取事件源
- stopPropagation() 取消冒泡
- preventDefault() 阻止默认行为
|
|
常见应用之事件委托
说明:需要给页面中成百上千个li绑定一个事件并且输出当前元素的innerHTML
常见做法
这种方式通过遍历DOM节点的方式添加事件处理程序有诸多缺点,比如性能大大减低,新添加的li不具备click事件等。
利用事件委托(冒泡原理)
利用事件委托可以大大地提高性能,后面随时添加的元素都可以拥有这个点击事件等