事件处理 客户端 js 程序采用异步事件驱动编程模型. 在这种情况下当文档, 浏览器, 元素发生一些事情的时候, 会产生事件.
举例 当浏览器加载完文档以后会触发一个事件. 该事件会有一个函数进行处理, 即回调函数
这种只不单单用于 web 界面, 所有使用图形界面的应用程序都采用了这种方式.
事件类型
事件分类
依赖于设备的输入事件
有些事件和特定输入设备直接相关. 比如鼠标和键盘.
touchmove 当触点在触控平面上时发生该事件
独立于设备的输入事件
click 事件表示激活了链接的事件. 通过鼠标, 按钮或者移动设备上的触摸触发该事件
用户界面事件
通常用于 html 表单元素, 包括文本输入域获取键盘焦点的 focus 事件, 提交按钮将会触发 submit 事件
状态变化事件
不是由用户活动由网络或者浏览器活动触发, 表示某种生命周期或相关状态的变化.
online 返回浏览器的联网状态
特定的 api 事件
一些 web api 会有自己的事件类型 拖放的 api dragstart 当用户拖动一个元素, 或者选择一个文本的时候触发该事件
计时器和错误处理程序
计时器在指定的时间后触发该事件, 错误处理程序, try catch 对应于一个响应, 会有异步进行抛出
传统事件类型
表单事件
当提交表单和重置表单时会触发 submit 和 reset 事件, 当用户和类按钮 (包括单选和复选) 交互的时, 将会发生 click 事件, 当用户输入文字, 选择选项或选择复选框改变相应的表单元素的状态时, 将会触发 change 事件, 通过键盘改变焦点的表单元素在得到和失去焦点时将会触发 focus 和 blur 事件. 通过事件处理程序能取消 submit 和 reset 事件的默认操作. 某些 click 事件也是如此, focus 和 clur 事件不会冒泡, 但其他所有表单事件都可以. 无论用户何时输入文字, 都会触发 input 事件.
window 事件
window 事件是指事件的发生与浏览器窗口本身而非窗口中显示的任何特定文档内容相关.
load 事件
load 事件与文档和其所有外部资源 (图片) 完全加载并显示给用户时将会触发.
unload 事件
unload 事件, 当用户离开当前文档转向其他文档时将会触发. unload 事件处理程序可以用于保存用户的状态, 但其不能取消用户转向其他地方.
beforeunload 事件
此事件将会询问用户是否确定离开当前页面. 如果 beforeunload 的回调函数返回一个字符串, 那么在新页面加载之前, 字符串将会出现在展示给用户确认的对话框上, 这样用户将会有机会取消跳转停留在当前页上
注意; 该事件仅仅是在当前页面的跳转更改等, 转换标签不会触发该事件
onerror 属性
此为一个 window 对象的属性. 在 js 出错的时候将会触发其
其他
像 img 元素这样的替换元素也能为其注册 load 和 error 事件处理程序. 当外部资源完全加载或发生阻塞加载错误时将会触发该事件. 某些浏览器也支持 about 事件, 当图强因为用户停止加载进程而导致失败的时候也会触发该事件. focus 和 blur 事件也为 window 事件, 当浏览器窗口从操作系统中得到或失去键盘焦点的时候将会触发该事件 当用户调整浏览器窗口大小或滚动其会触发 resize 和 scroll 事件, scroll 事件也能在任何可以滚动的文档元素上触发, 例如 CSS 的的 overflow 属性也能触发.
鼠标事件
当用户在文档上移动和单击鼠标时都会产生鼠标事件. 这些事件在鼠标指针所对应的最深嵌套元素上触发. 但其会冒泡直到文档的最顶层. clientX 和 clientY 属性指定了鼠标在窗口坐标中的位置. button 和 which 属性指定了按下的鼠标键是哪个. 当鼠标辅助键按下的时候, 对应的属性为 altkey 和 ctrlkey 和 metakey 和 shiftkey 会设置为 true, 对于 click 事件, detail 属性指定了其是单击, 双击, 还是三击. 每当用户移动和拖动鼠标时, 会触发 mousemove 事件, 当用户按下或释放鼠标按键的时候触发 mousedown 和 mouseup 事件. 在 mousedown 和 mouseup 事件队列之后, 浏览器也会触发 click 事件, 如果用户在很短的时间内单击两次鼠标, 则第二个事件为 dblclic 事件, 当单击鼠标右键时, 浏览器会显示上下文菜单, 在显示菜单之前, 也会触发 contextmenu 事件, 如果取消这个事件将会阻止菜单的显示, 该事件为获得鼠标右击通知的最简单方法. 当用户移动鼠标指针从而使它悬停到新元素上时, 浏览器就会在该元素上触发 mouseover 事件, 当鼠标移动指针从而使它不在悬停在某个元素上时, 浏览器会触发 mouseout 事件,(该事件有 relatedTarget 属性指明这个过程涉及的其他元素) 当用户滚动鼠标的时候, 浏览器触发 mousewheel 事件, 传递事件对象属性指定轮子转动的大小和方向.
键盘事件
当键盘聚焦到 web 浏览器时, 用户每次按下或释放键盘上的按键时都会产生事件, 键盘快捷键叶同样能被浏览器和操作系统吃掉, 此时对 js 事件处理程序不可见, 无论任何文档元素获取键盘焦点都会触发键盘事件, 并会冒泡到 window 对象,
触摸屏和移动设备事件
用户旋转设备的时会产生 orientationchange 事件, 有一个缩放和旋转手势, 当手势开始时将会生成 getsturestart 事件, 手势结束时将会生成 gestureend 事件. 在这两个事件之间是跟踪手势过程的 gesturechange 事件队列, 将事件传递的事件对象属性为 scale 和 rotation
握紧手势的 scale 值小于 1.0 撑开手势的 scale 的值大于 1.0 rotation 为事件开始时手指旋转的角度. 以度为单位正值表示顺时针方向旋转
当手指触摸屏幕的时候将会触发 touchstart 事件, 当手指移动时会触发 touchmove 事件, 当手指离开屏幕时会触发 touchend 事件, 触摸事件传递的事件对象有一个 changedTouches 属性, 该属性为一个类数组对象, 其每个元素都描述触摸的位置.
当设备允许用户从竖屏旋转到横屏模式时会在 window 对象上触发 orientationchanged 事件. 该对象的 orientation 属性能给出当前方位, 其值为 0, 90, 180, 或 -90
注册事件处理程序
给事件目标对象或文档元素设置属性
将事件处理程序传递给对象或文档元素的一个方法
设置 js 对象属性为事件处理程序
事件处理程序属性的名字由 on 后面跟着事件名组成. onclick,onchange,onload,onmouseover
onload 当对象的资源被加载的时候, 该对象的 onload 事件将会被触发, 然后将表单的提交的 onsubmit 事件和一个处理函数进行绑定
onsubmit 在表单提交的时候, 将会触发该事件
下方栗子演示一个提交的时候表单验证的过程 其中 validate 函数为一个自定义的表单验证函数, 其函数的参数 this 指向 elt
- window.onload = () => {
- // 查找一个 < form > 元素
- var elt = document.getElementById("shipping_address");
- // 注册事件处理程序函数
- // 在表单提交之前调用该函数
- elt.onsubmit = () => { return validate(this); };
- }
复制代码
设置 HTML 标签属性为事件处理程序
<button onclick="alert('Thank you');">点击这里</button>
复制代码
点击按钮会弹出一个对话框
addEventListener()
为事件绑定一个处理的函数
<script>
var b = document.getElementById("my button");
b.onclick = () => { alert("Thanks for clicking me!"); };
b.addEventListener("click", () => { alert("Thanks again!"); }, false); // 最后一个参数为是否进行冒泡
</script>
复制代码
上方会弹出两个对话框, 一个触发了 onclick 事件, 一个触发了 addEventListener 注册的 click 事件. 注册的 click 处理的函数, 将会按照注册的顺序依次不断的调用.(可以注册多个处理程序).
document.removeEventListener("mousemove", handleMouseMove, true);
复制代码
移出在 mousemove 上注册的事件, 处理函数为 handLenMouseMove, 在事件上直接注册, 没有冒泡的过程.
事件处理程序的调用
事件处理程序运行的环境
this 关键字指的是事件的目标.
事件处理程序的作用域
这是个坑的集散地, 表单上有一个 HTML 事件处理程序想要引用 window 的 location 对象, 必须使用 window.location, 不能使用 location, 因为该 location 为表单作用域链上的 location
事件处理程序的返回值
如果返回 false 则告诉浏览器不要执行这个事件的默认操作.
调用顺序
通过设置对象属性, HTML 属性注册的处理程序一直优先调用 使用 addEventList 注册的处理程序, 按照 DOM 的顺序进行调用 使用 attachEvent()注册的事件按照随机的顺序调用
事件传播
当事件目标为 window 对象或其他一些单独对象, 浏览器会简单的调用对象上的处理程序响应事件.
调用目标元素上注册的事件处理函数
在调用目标元素上注册的事件处理函数的时候, 该事件会冒泡到 DOM 树的树跟, 调用目标的父元素的事件处理程序, 即可以在共同的祖先元素上注册一个处理程序来处理所有的事件 例如: 在 form 元素上注册 change 事件处理程序取代在表单的每个元素上注册 change 事件处理程序. 原因: 冒泡
注意: load 事件,(load 当资源加载完成以后, 将会触发 load 事件, 不单单指整个文档)其会在 Document 对象上停止冒泡不会传播到 window 对象, 只有整个文档都加载完成的时候将会触发 window 对象的 load 事件
捕获
事件的第一阶段 捕获 发生在目标处理程序调用程序之前 addEventener()把一个布尔值作为其第三个参数, 如果为 true 那么事件处理程序被注册为捕获事件处理程序, 会在事件传播的第一个阶段调用. 事件传播的捕获阶段像是反向的冒泡,, 将会最先调用 window 对象的捕获处理程序, 然后将会调用 document 对象的捕获处理程序, 接着是 body 对象的捕获处理程序, 逐渐按照 DOM 树往下, 直到调用事件目标的父元素的捕获事件捕获.
事件取消
通过调用事件对象的 preventDefault()方法取消事件的默认操作.
文档加载事件
web 应用需要 web 浏览器通知它们文档加载完毕和为操作准备就绪的时间. 当文档准备就绪的时候调用函数
事件冒泡和传播
事件冒泡属于微软的, 向上 事件传播属于网景浏览器(怀旧, 一个时代, 可惜已经不存在了), 正好相反. 后来 w3c 将这两种给统一了, 规定任何事件首先向下传播直到遇到目标元素, 如果没有遇到冒泡元素, 将会不断的向上冒泡进行返回. 的
来源: https://juejin.im/post/5b6ff57651882560ed075406