第十七章:事件
17.1 事件流
- 描述了页面接收事件的顺序
17.1.1 冒泡事件
17.1.2 事件捕获
17.1.3 DOM 事件流
- 事件流的三个阶段:事件捕获、到达事件、事件冒泡
17.2 事件处理程序
17.2.1 HTML 事件处理程序
17.2.2 DOM0 事件处理程序
let btn = document.getElementById("myBtn");
btn.onclick = function () {
console.log("Clicked");
};
17.2.3 DOM2 事件处理程序
addEventListener()
- 第三个参数为布尔值,表示是否在捕获节点调用事件处理程序,默认为 false
removeEventListener()
let btn = document.getElementById("myBtn");
// 可以给同一个时间添加多个处理程序
btn.addEventListener("click", () => {
console.log(this.id);
}, false);
- 多个处理程序按添加顺序执行
17.2.4 IE 事件处理程序
attachEvent()
- 处理程序的作用域为全局作用域
detachEvent()
- 多个处理程序按添加顺序反向执行
17.2. 跨浏览器事件处理程序
cancel ## 17.3 事件对象 ### 17.3.1 DOM 事件对象 - 事件处理程序内部的 ```this```始终等于 ```event.currentTarget``` - ```event.target```只包含事件的实际目标 - ```preventDefault()``` - 任何可以通过该方法取消默认事件的事件,其事件对象的 ```cancelable```属性为 true - ```stopPropagation()```:取消后续的事件捕获或冒泡
17.3.2 IE 事件对象
- p502(第四版)
17.3.3 跨浏览器事件对象
17.4 事件类型
- DOM3 事件类型:
- 用户界面事件:涉及与 BOM 交互的通用浏览器事件
- 焦点事件
- 鼠标事件
- 滚轮事件
- 输入事件
- 键盘事件
- 合成事件:使用某种 IME(输入法编辑器)输入字符时触发
17.4.1 用户界面事件
DOMActivate
:元素被用户通过鼠标或键盘操作激活时触发load
:加载完成后触发unload
:完全卸载后触发abort
:在<object>
元素上当响应对象加载完成前被用户提前终止下载时触发error
select
:在文本框上当用户选择了一个或多个字符时触发resize
scroll
1. load 事件
- window 对象上,在整个页面(包括外部资源)加载完成后触发
- 图片加载完成后触发
- 要在设置 scr 属性之前附加事件处理程序
<script>
元素加载完 js 文件后触发
2. unload 事件
- 一般在从一个页面导航到另一个页面时触发,最常用于清理引用
- 与 load 事件一样可以设置在
<body>
上
3. resize 事件
4. scroll 事件
17.4.2 焦点事件
blur
:当元素失去焦点时触发,不冒泡focus
:当元素获得焦点时触发,不冒泡focusin
:focus 冒泡版focusout
:blur 冒泡版
- 事件顺序:
focusout
:在失去焦点的元素上触发focusin
:在获得焦点的元素上触发blur
focus
17.4.3
click
:单击鼠标主键(通常是左键)或回车键时触发dblclick
:双击mousedown
:按下任意鼠标键mouseenter
:鼠标从元素外移动到元素内,不冒泡,经过后代元素不触发mouseleave
:不冒泡mousemove
:鼠标在元素上移动时反复触发mouseout
:移到另一元素上时触发,目标元素可以是外部元素或者子元素mouseover
mouseup
:释放鼠标按键时触发
- 事件顺序:
mousedown
mouseup
click
mousedown
mouseup
click
dbclick
- 前置事件取消会影响后续事件
mousewheel
:滚轮事件
1. 客户端鼠标
event.clientX / clientY
:鼠标在浏览器视口中的坐标- 不考虑页面滚动
2. 页面坐标
event.pageX / pageY
:页面坐标
3. 屏幕坐标
event.screenX / screenY
4.修饰键
event.shiftKey / ctrlKey / altKey / metaKey
:布尔值
5. 相关元素
event.relatedTarget
mouseover
,mouseout
6. 鼠标按键
event.button
:0 表示主键,1 表示中键, 2 表示副键mousedown
,mouseup
7. 额外事件信息
event.detail
:在鼠标事件中表示单击次数。按下与抬起之间移动会重置为 0
8. mousewheel 事件
event.wheelDelta
:向前滚动为 +120, 向后滚动为 -120
9. 触摸屏设备
10. 无障碍问题
17.4.4 键盘与输入事件
- 键盘事件:
keydown
:持续按住会重复触发keypress
:按下并产生字符时触发,持续按住会重复触发(DOM3废弃,推荐使用textInput
)keyup
- 输入事件:
textInput
:文本被插入到文本框之前触发
1. 键码
event.keyCode
keydown
,keyup
2. 字符编码
event.charCode
keypress
3. DOM3 的变化
key / char
location
:表示在哪里按的键getModifierState()
:接收修饰键的字符串,返回布尔值表示是否处于激活状态
4. textInput
事件
- 只在可编辑区触发
event.data
:表示要被插入的字符event.inputMethod
:表示输入手段,如粘贴、键盘等
5. 设备上的键盘事件
- 任天堂yyds
17.4.5 合成事件
- p522(第四版)
17.4.6 变化事件
- 已被废弃,参考第 14 章的
Mutation Observers
17.4.7 HTML5 事件
1. contextmenu
事件
- 冒泡
myDiv.addEventListener("contextmenu", (event) => {
event.preventDefault();
// position: absolute
let menu = document.getElementById("myMenu");
menu.style.left = event.clientX + "px";
menu.style.top = event.clientY + "px";
menu.style.visibility = "visible";
});
2. beforeunload
事件
3. DOMContentLoaded
事件
- 在 DOM 树构建完成后立刻触发
4. readystatechange
事件
- p525(第四版)
5. pageshow
与 pagehide
事件
- 必须添加到 window 对象上
pageshow
event.persisted
:页面存储在了往返缓存中则为 true
pagehide
event.persisted
:为 true 表示页面在卸载后会被保存到往返缓存中
6. hashchange
事件
- p528(第四版)
17.4.8 设备事件
- p528(第四版)
17.4.9 触摸及手势事件
- p531(第四版)
17.4.10 事件参考
- p534(第四版)
17.5 内存与性能
17.5.1 事件委托
- 利用事件冒泡
17.5.2 删除事件处理程序
- 删除节点前先清空事件处理程序
- 页面卸载前通过 onunload 删除所有事件处理程序
- 使用 onunload 意味着页面不会被保存到往返缓存中
17.6 模拟事件
17.6.1 DOM 事件模拟
document.createEvent()
,参数:UIEvents
MouseEvents
HTMLEvents
dispatchEvent()
:参数为要触发事件的 event 对象
1. 模拟鼠标事件
- p544(第四版)
let btn = document.getElementById("myBtn");
let event = document.createEvent("MouseEvents");
// 事件类型 是否冒泡 是否可以取消 关联的视图
event.initMouseEvent("click", true, true, document.defaultView);
2. 模拟键盘事件
3. 模拟其他事件
4. 自定义 DOM 事件
17.6.2 IE 事件模拟
- p547(第四版)