事件
理解事件流
事件流描述页面接收事件的顺序
- 事件冒泡流(IE和现代浏览器),由最具体的元素传播到不具体的节点。建议使用
- 事件捕获流(现代浏览器),由不具体的节点到具体的节点
DOM2级事件
规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
Tips: IE9及以上才全部实现 DOM2级
事件(事件流)。
使用事件处理程序
事件就是用户或者浏览器执行的某种动作,而响应某个事件的函数就叫做事件处理程序。
- HTML 事件处理程序
- 就是在 HTML 直接写 JS,基本很少使用,耦合性太强
- DOM0 级事件处理程序
- 获取元素后直接对元素
ele.onxx
进行函数赋值,可以通过ele.onxxx = null;
删除事件,全部浏览器都支持,但每种事件只能绑定一种方法。 - 事件处理程序会在冒泡阶段被处理
this
指的是元素作用域
- 获取元素后直接对元素
- DOM2 级事件处理程序
- 接受三个参数(事件名/处理函数/布尔值 true为捕获,false为冒泡)
- addEventListener()
- removeEventListener()
- 可以添加多个事件处理程序,按顺序执行。
this
指的是元素作用域
- 接受三个参数(事件名/处理函数/布尔值 true为捕获,false为冒泡)
- IE 事件处理程序
- IE9 之前只支持事件冒泡,所以 IE 事件处理程序是在冒泡阶段执行。只接受两个参数(
on
+ 事件名/处理函数)
- attachEvent()
- detachEvent()
- 可以添加多个事件处理程序,后添加的先执行。
this
指的是window
- IE9 之前只支持事件冒泡,所以 IE 事件处理程序是在冒泡阶段执行。只接受两个参数(
事件对象
触发 DOM 事件的时候产生的对象 event
。
- DOM 中的事件对象(DOM0 & DOM2)
- 可以直接在事件处理程序中获取
event
- 事件属性和方法如下
- bubbles 是否冒泡
- stopPropagation() 取消事件进一步捕获/冒泡
- cancelable 是否可以取消事件默认行为
- preventDefault() 取消事件默认行为
- currentTarget 正在处理事件的元素
- target 事件的实际目标
- defaultPrevented
- detail
- eventPhase 事件处理的阶段
- stopImmediatePropagation()
- trusted
- type
- view
- 可以直接在事件处理程序中获取
Tips: 在事件处理程序内部,对象
this
始终等于currentTarget
的值,而target
只包含事件的实际目标。也就是说直接点击目标元素的时候,这三个值相等;如果点击父节点(比如body
)触发事件程序,此时this
等于currentTarget
,而target
元素指向真正的目标(比如body
上的按钮)。IE9 及以上/现代浏览器都支持 DOM 事件操作。
- IE 中的事件对象(
IE9
以下)
- DOM0 通过
window
可以访问event
,直接获取参数的event
会是undefined
attachEvent()
添加的事件可以通过参数访问也可以通过window
访问- 事件的属性和方法
- cancelBubble 是否取消冒泡(对应
stopPropagation
) - returnValue 是否阻止默认行为(对应
preventDefault()
) - srcElement 事件的目标(即 DOM 中的
target
) - type
- cancelBubble 是否取消冒泡(对应
- DOM0 通过
IE9 以下事件中的
this
恒等于event.srcElement
.
事件类型
- DOM3 级别,重新定义了 DOM2 中的一些事件,也新增了一些事件。(了解常用的即可,其他可以上网查询,具体内容可以去 w3c 查看)
- UI 事件
- 焦点事件
- 鼠标事件
- 滚轮事件
- 文本事件
- 键盘事件
- 合成事件
- 变动事件
*内存和性能
事件委托
- 利用事件冒泡,只给一个
DOM
元素添加事件处理程序(节省资源),再根据实际target
进行处理。 - 比较适合采用事件委托的事件(click/mousedown/mouseup/keydown/keyup/keypress)
- 利用事件冒泡,只给一个
移除事件和处理程序
- 对于某些直接移除的元素(但还保留事件处理),可以在移除之前先移除事件(remove/null)
- 通过
onunload
事件移除所有事件处理程序。
Tips:如果使用了事件委托,就没那么麻烦,因为全部事件都只绑定在一个
DOM
上。
模拟事件
DOM 中的事件模拟
createEvent()创建对象
dispatchEvent()触发事件
IE 中的事件模拟
createEventObject()创建 event 对象
fireEvent()触发事件
小结
- 要理解事件相关知识点。
- 从性能方面考虑,不要滥用事件处理程序。
- 可以多用事件委托技术。
- 浏览器卸载页面之前移除所有事件处理程序(目前来说这个应该不需要了,浏览器应该已经有处理了)
- 可以使用 js 模拟事件(这个感觉用处不会很大,要用的时候再搜索一下就足够了)