事件处理
客户端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将这两种给统一了,规定任何事件首先向下传播直到遇到目标元素,如果没有遇到冒泡元素,将会不断的向上冒泡进行返回。