Event对象与自定义事件
事件对象
当为DOM
元素添加一些事件的回调函数后,事件被触发时,会传给回调函数一个Event
对象作为第一个参数;而这个Event
对象包含关于触发的事件的一些信息及处理方法。
常用属性
bubbles
:Boolean
(只读), 表明事件是否冒泡;cancelable
:Boolean
(只读), 表明是否可以取消事件的默认行为;currentTarget
:Element
(只读),事件处理程序当前正在处理事件的那个元素;defaultPrevented
:Boolean
(只读), 为true
表示已经调用了preventDefault()
(DOM3
级事件中新增)detail
:Integer
(只读),与事件相关的细节信息;eventPhase
:Integer
(只读),调用事件处理程序的阶段:1
表示捕获阶段,2
表示『处于目标』(即currentTarget
与target
一致时),3
表示冒泡阶段;target
:Element
(只读),事件的目标;type
:String
(只读),被触发的事件的类型;view
:AbstractView
(只读),与事件关联的抽象视图。等同于发生事件的window
对象;
整理自《JavaScript 高级程序设计》
常用方法
preventDefault()
:Function
(只读),取消事件的默认行为。如果cancelable
是true
,则可以使用这个方法;stopImmediatePropagation()
:Function
(只读),取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3
级事件中新增)stopPropagation()
:Function
(只读),取消事件的进一步捕获或冒泡。如果bubbles
为true
,则可以使用这个方法;
整理自《JavaScript 高级程序设计》
DOM事件流
“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
构建自定义事件
构建一个自定义事件的关键就是:
-
拦截原生事件,阻断原事件传播:利用
addEventlistener
的第三个参数,可以在某父级DOM
上事件传播的捕获阶段触发回调函数,然后使用stopPropagation
方法阻止原事件的进一步传递; -
构造自定义
Event
对象:利用Event
构造函数构造一个自定义属性的事件对象; -
派发自定义事件:使用
EventTarget
对象自带的dispatchEvent
方法进行事件对象的派发;
addEventlistener方法
1 | target.addEventListener(type, listener[, useCapture]) |
addEventListener
可以为DOM
绑定一个DOM2
级事件的监听处理,一般第三个参数useCapture
很少使用,其作用就是该事件是否在捕获阶段触发,默认为false
,因此设置为true
时可在捕获阶段触发监听处理函数!
创建Event对象
event = new Event(typeArg, eventInit);
通过Event
构造函数可以创建一个自定义属性的Event
对象,相当于回调函数接收的第一个参数;
typeArg
:事件的名称;eventInit
:事件的设置选项,为一个对象,该对象可以使用以下属性:bubbles
:Boolean
类型,表示该事件是否可以冒泡,默认值为false
;cancelable
:Boolean
类型,表示该事件是否可以使用preventDefault()
方法进行取消,默认为false
;composed
:Boolean
类型,事件是否会在影子DOM
根节点(shadow root DOM
)之外触发侦听器,默认为false
;
dispatchEvent()
EventTarget.dispatchEvent(event)
EventTarget
:一般为触发事件时Event
对象的target
属性所指向的DOM
节点;event
:Event
对象;
使用该方法就相当于某个DOM
节点触发了某个event
事件;
案例:自定义tap事件
由于现在的移动端设备的屏幕多是触摸屏,因此H5
针对触摸屏特别制定了适用于触摸设备的TouchEvent
事件规范,这使得触摸屏的点击事件变得更加灵敏了;
为啥使用click
事件就不灵敏了?由于一些历史原因,现在的移动端浏览器对于click
事件和touch event
事件的执行顺序遵守如下规则:touchstart->touchmove->touchend->wait 300ms->click
;没错,click
要在所有的touch event
执行完后延迟300ms
再执行;
因此,如果在移动端使用click
事件在点击时会出现一个很明显的延迟,对于用户体验来说是不利;其中一个解决办法就是利用TouchEvent
封装一个tap
点触事件,消除300ms
的延迟:
1 | function initTap(eventType = 'tap') { |
上面给出的initTap
方法实际上是在body
元素上(也就是全局)劫持TouchEvent
事件,只要判断不是touchmove
事件,那么在touchend
事件阶段就会在target
对象上派发一个自定义的tap
事件,即相当于在touchend
事件后马上触发,因此也就没有click
事件的300ms
延迟,反应特别灵敏;这种方法可以直接在Vue
中利用v-on/@
进行监听(如@tap="xxx"
),十分方便!
而且TouchEvent
在移动端的兼容性非常好,可以大胆的使用: