事件对象是事件的基础,事件都不是独立存在的,须要绑定在一个事件对象上,监听对象的变化,当对象发生相关事件变化时触发对应回调。前端
window, document, Element都是EventTarget对象,一些非节点元素也是EventTarget,好比Ajax中的XMLHttpRequest对象数组
利用addEventListener
能够给EventTarget
增长Event
事件,方法接受最多三个参数:浏览器
addEventListener(type, listener[, options/capture])
bash
type
: 事件类型,能够是浏览器支持的DomEvent
,也能够是本身自定义的CustomEvent
前端框架
listener
: EventListener
,UserAgent
将事件发送给EventListener
的时候,会触发listener
对象中的handleEvent
方法。因为历史遗留,一般咱们写EventListener
的时候第二个参数都是一个方法网络
eventTarget.addEventListener('click', ev => {})
复制代码
实际上等价于框架
eventTarget.addEventListener('click', {handleEvent: ev => {}})
复制代码
options/caputure
: 第三个参数为可选,接受一个Object
/Boolean
,接受Object
能够指定三个属性:capture
, once
, passive
ide
capture: 设置事件捕获方式,默认为
false
,不使用捕获,事件使用冒泡机制;设置为true
,使用捕获机制
once: 事件是否只触发一次
passive:EventListener
内部是否可使用event.preventDefault()
,设置为true的时候将不能使用,不然会提示错误信息:Unable to preventDefault inside passive event listener invocation.
函数
简明一下浏览两种事件触发机制:冒泡和捕获,冒泡是从内向外,捕获是从外向内,借用网上经典的一个图示来讲明:动画
PS:
IE
浏览器使用attachEvent
来做为addEventListener
的替代方法document.addEventListener('click', () => {console.log('click')})
document.addEventListener('click', () => {console.log('click')})
复制代码
这样进行绑定,当点击页面的时候会触发两次,可是若是按照如下方式进行绑定,则只会触发一次
function click() {
console.log('click')
}
document.addEventListener('click', click)
document.addEventListener('click', click)
复制代码
移除绑定的EventListener
对象
removeEventListener(type, listener[, useCapture])
一样支持三个参数,第一个参数type
为移除的事件类型,第二个参数为EventListener
对象,必须和addEventListener
添加的对象是同一个对象/方法,第三个参数为移除冒泡仍是移除捕获的事件
一般咱们经过增长部分已经被定义的EventListener
事件类型,例如:click
, input
等,直到用户发生交互行为或EventTarget
对象操做结束,触发绑定的事件;除此之外,其实能够自定义EventTarget
以及CustomEvent
,而且利用dispatchEvent
在任意时候手动触发相关事件,例如:
let eventTarget = new EventTarget();
let event = new CustomEvent('myEvent', {detail: 'test' });
eventTarget.addEventListener('myEvent', () => {
console.log('trigger event')
})
eventTarget.dispatchEvent(event);
复制代码
Event
是全部Event
对象的基类,包含了一些基础的属性
bubbles
: 判断事件是否冒泡
cancelable
: 判断事件是否能够取消
composed
: 判断事件是否能够从ShadowDom
传递到ShadowDom
currentTarget
: 事件注册的对象
defaultPrevented
: 判断事件是否执行了preventDefault()
eventPhase
: 得到事件触发阶段(0: Event.NONE
, 1: Event.CAPTURE_PHASE
捕获阶段, 2: Event.AT_TARGET
到达触发目标阶段, 3: Event.BUBBLING_PHASE
冒泡阶段)
target
:事件发送的原始目标,和currentTarget
区别在于,currentTarget
是事件注册的目标(有多是target
的父节点)
type
: 触发事件类型
timeStamp
: 事件从建立成功后到触发时所用的时间,单位毫秒
isTrusted
: 判断事件是用户触发仍是非用户触发,true
表明用户触发的事件
cancelBubble
: Event.stopPropagation()
历史别名,设置为true
之后会阻止事件冒泡
returnValue
: 已经被preventDefault()
替代,设置为false
之后会阻止默认的事件
srcElement
: IE
旧版本浏览器中的target
对象
composedPath()
: 获取触发事件路径,会返回从target
到Window
的事件路径数组
preventDefault()
: 阻止默认的事件,例如input
的默认事件是输入,若是keyup/keydown
事件使用了preventDefault()
,则输入框将没法输入字符
stopImmediatePropagation()
: 阻止其余type
相同的事件的触发,也就是同一个EventTarget
的相同type
事件只会触发一个
stopPropagation()
:阻止事件的冒泡/捕获
大部分的type
事件有特定事件类型,不一样的浏览器对具体事件类型支持的程度不一而同,列举一些经常使用的事件子类,及会获得该子类的type
类型
blur
: 失去焦点,不会冒泡
focusout
: 失去焦点,支持冒泡
focus
: 得到焦点,不会冒泡
focusin
: 得到焦点,支持冒泡
mouseenter
: 鼠标移入元素
mouseleave
: 鼠标移出元素
mouseover
: 鼠标移入元素/子元素(给父元素绑定之后,从父元素到子元素,或者从子元素到父元素都会触发)
mouseout
: 鼠标移出元素/子元素
mousemove
: 鼠标在元素上持续移动
mousedown
: 鼠标在元素上点击
mouseup
: 鼠标在元素上释放点击
click
: 鼠标点击(按下和释放必须同时触发),支持冒泡
dbclick
: 鼠标双击
contextmenu
: 鼠标右键打开菜单栏(监听该事件后可使用event.preventDefault()阻止打开右键菜单)
wheel
: 鼠标滚轮的滚动
有只读的data
属性,event.data
能够获取到正在输入到字符串
compositionend
: 段落文本组成完成,好比:输入法组件关闭
compositionstart
: 文字输入前触发,不一样于keydown
,在输入法控件打开时候触发(听说也支持语音识别打开)
compositionupdate
: 输入法打开后,文字输入过程触发
error
: 资源加载失败,页面throw Error()
能够进行捕获
input
: 对于<input type="text">, <textarea>, <select>
元素值发生更改时同步触发,对于<input type="radio">, <input type="checkbox">
的元素,每次切换控件时触发,contenteditable=true
内的内容变动也会触发
change
: 不一样于input
,不必定每一次变化都会触发,焦点遗失/会车等操做会触发
keydown
: 键盘按键按下,不管是否产生字符都会触发
keypress
: 键盘按键按下,产生字符时触发,所以ctrl
,shift
不产生字符都键位不会触发
keyup
: 键盘按键释放
animationstart
: CSS动画开始
animationedn
: CSS动画结束
animationiteration
: CSS动画重复开始时触发
*transtionstart
: CSS中transition
实际发生时,会在transition-delay
后触发,实验性质事件
transitionend
: CSS的transition
结束的时候触发
*transitionrun
: transition-delay
前触发,实验性质事件
cut
: 发生剪切时触发,包括键盘快捷键和菜单栏中的操做
copy
: 发生复制时触发,包括键盘快捷键和菜单栏操做和document.execCommand('copy')
,能够经过event.preventDefault()
阻止复制,能够经过event.clipboardData.setData()
和getData()
来获取内容
paste
: 发生粘贴时触发
主要是使用在触屏上的监听
touchcancel
: 一个或者多个触点触碰时,草畜了触点支持的数量而被取消时触发
touchend
: 一个或多个触点触碰结束时触发
touchemove
: 一个或多个触点移动的时候触发
touchstart
: 一个或多个触点开始触碰时触发
因为屏幕设备的扩展,因此操做手段不在局限于鼠标,因此提供了一套和鼠标操做相同的API,来支持相似的触控事件
pointerover
: 和mouseover
等同
pointerenter
: 和mouseenter
等同
pointerdown
: 和mousedown
等同
pointermove
: 和mousemove
等同
pointerup
: 和mouseup
等同
pointerout
: 和mouseout
等同
pointerleave
: 和mouseleave
等同
拖动相关事件,其实分为了拖动元素事件和释放区域事件两类
拖动元素事件:
dragstart
: 元素开始拖动
drag
: 元素拖动中(每350ms触发一次)
dragend
: 元素拖动结束
释放区域事件
dragenter
: 拖动进入了drop目标区域,进入子节点也会反复触发
dragover
: 元素在drop目标区域中移动(每350ms触发一次),须要设置event.preventDefault()
元素才能在该区域drop
dragleave
: 拖动离开了drop目标区域,进入子节点也会触发
drop
: 元素在drop目标区域中拖动被释放
媒体播放相关事件,针对H5视频<video>
和音频<audio>
播放器的事件
durationchange
: duration属性更新
loadedmetadata
: metadata属性加载
loadeddata
: media完成加载
canplay
: 能够播放media的时候触发(拖动进度条会触发)
canplaythrough
: 能够播放整个media时触发(拖动进度条会触发)
ended
: media播放结束触发
stalled
: 请求media数据,可是剧没有如预期到来时触发
suspend
: media请求挂起时触发
play
: media播放开始
playing
: media播放中
pause
: media暂停
waiting
: 缺乏数据加载
seeking
: 时间进度条操做变更
seeked
: 时间进度条操做变更中止
ratechannge
: 播放速率改变
timeupdate
: currentTime属性更新(播放过程当中时间变更)
volumechange
: 音量调节
select
: 文本选中,只能监听input
和textarea
的选中(该事件和document.execCommand('copy')
能够实现点击复制功能)
DOMContentLoaded
: DOM
加载完成,不会等待样式,图片渲染,Chrome中的devtool中Network中能够看到相关加载时间应该就是使用该监听来处理的
beforeunload
: 离开页面前触发,设置event.returnValue=true
,将弹出提示消息来确认是否关闭
offline/online
: 在浏览器丢失网络/得到网络时触发
beforeprint
: 准备打印/打开打印预览时触发
afterprint
: 开始打印/关闭打印预览后时触发
reset/submit
: 表单重置/提交按钮点击时触发
fullscreenchange/resize/scroll
:浏览器全屏/尺寸修改/滚动时触发
hashChange
: URL中#以及#后面的值发生变化的时候触发,可能前端框架的路由机制能够用该监听实现
readstatechange
: document
的readyState
发生变化的时候触发,能够做为DomContentLoaded
的替代
invalid
: h5表单提交,绑定元素不符合规则的时候触发(input元素能够设置验证规则属性,例如:required
, max
, min
, pattern
,能够经过伪类:invalid
获取到数据)
message
: WebWorks信息接受时触发
在 1.2.3 dispathEventListener 中提到了CustomEvent
,能够根据本身的需求定义事件,并经过dispatchEvent
来触发绑定的自定义事件