DOM3 Events定义了如下事件类型:
❑ 用户界面事件(UIEvent):涉及与BOM交互的通用浏览器事件。
❑ 焦点事件(FocusEvent):在元素获得和失去焦点时触发。
❑ 鼠标事件(MouseEvent):使用鼠标在页面上执行某些操作时触发。
❑ 滚轮事件(WheelEvent):使用鼠标滚轮(或类似设备)时触发。
❑ 输入事件(InputEvent):向文档中输入文本时触发。
❑ 键盘事件(KeyboardEvent):使用键盘在页面上执行某些操作时触发。
❑ 合成事件(CompositionEvent):在使用某种IME(Input MethodEditor,输入法编辑器)输入字符时触发。除了这些事件类型之外,HTML5还定义了另一组事件,而浏览器通常在DOM和BOM上实现专有事件。

17.4.1 用户界面事件

用户界面事件或UI事件不一定跟用户操作有关。
这类事件在DOM规范出现之前就已经以某种形式存在了,保留它们是为了向后兼容。
UI事件主要有以下几种:
❑ DOMActivate:元素被用户通过鼠标或键盘操作激活时触发(比click或keydown更通用)。这个事件在DOM3 Events中已经废弃。因为浏览器实现之间存在差异,所以不要使用它。
❑ load:在window上当页面加载完成后触发,在窗套()上当所有窗格()都加载完成后触发,在17.4 事件类型 - 图1元素上当图片加载完成后触发,在元素上当相应对象加载完成后触发。
❑ unload:在window上当页面完全卸载后触发,在窗套上当所有窗格都卸载完成后触发,在元素上当相应对象卸载完成后触发。
❑ abort:在元素上当相应对象加载完成前被用户提前终止下载时触发。
❑ error:在window上当JavaScript报错时触发,在17.4 事件类型 - 图2元素上当无法加载指定图片时触发,在元素上当无法加载相应对象时触发,在窗套上当一个或多个窗格无法完成加载时触发。
❑ select:在文本框(或textarea)上当用户选择了一个或多个字符时触发。
❑ resize:在window或窗格上当窗口或窗格被缩放时触发。
❑ scroll:当用户滚动包含滚动条的元素时在元素上触发。

1.load事件

在window对象上,load事件会在整个页面(包括所有外部资源如图片、JavaScript文件和CSS文件)加载完成后触发。
可通过两种方式指定load事件处理程序:
第一种是JavaScript方式;
第二种指定load事件处理程序的方式是向元素添加onload属性;

  1. // 使用addEventListener()方法来指定事件处理程序
  2. window.addEventListener('load', (event) => {
  3. console.log('Loaded!');
  4. });
  5. <body onload="console.log('Loaded!')"></body>

注:根据DOM2 Events, load事件应该在document而非window上触发。但为了向后兼容,所有浏览器都在window上实现了load事件。
图片上也会触发load事件,包括DOM中的图片和非DOM中的图片

2.unload事件

与load事件相对的是unload事件,unload事件会在文档卸载完成后触发。
unload事件一般是在从一个页面导航到另一个页面时触发,最常用于清理引用,以避免内存泄漏。
与load事件类似,unload事件处理程序也有两种指定方式:
第一种是JavaScript方式;
第二种方式与load事件类似,给元素添加onunload属性;

  1. window.addEventListener('unload', (event) => {
  2. console.log('Unloaded!');
  3. });
  4. <body onunload="console.log('Unloaded!')"></body>

unload事件是在页面卸载完成后触发的,所以不能使用页面加载后才有的对象。此时要访问DOM或修改页面外观都会导致错误。
注:根据DOM2 Events, unload事件应该在而非window上触发。但为了向后兼容,所有浏览器都在window上实现了unload事件。

3.resize事件

当浏览器窗口被缩放到新高度或宽度时,会触发resize事件。
这个事件在window上触发,因此可以通过JavaScript在window上,或者为元素添加onresize属性来指定事件处理程序。优先使用JavaScript方式。

  1. window.addEventListener('resize', (event) => {
  2. console.log('Resized!');
  3. });

不同浏览器在决定何时触发resize事件上存在重要差异。IE、Safari、Chrome和Opera会在窗口缩放超过1像素时触发resize事件,然后随着用户缩放浏览器窗口不断触发。Firefox早期版本则只在用户停止缩放浏览器窗口时触发resize事件。
无论如何,都应该避免在这个事件处理程序中执行过多计算。否则可能由于执行过于频繁而导致浏览器响应明确变慢。
注:浏览器窗口在最大化和最小化时也会触发resize事件。

4.scroll事件

虽然scroll事件发生在window上,但实际上反映的是页面中相应元素的变化。
在混杂模式下,可以通过元素检测scrollLeft和scrollTop属性的变化;
在标准模式下,这些变化在除早期版的Safari之外的所有浏览器中都发生在元素上(早期版的Safari在上跟踪滚动位置)

  1. // 处理这些差异
  2. window.addEventListener('scroll', (event) => {
  3. if (document.compatMode == 'CSS1Compat') {
  4. console.log(document.documentElement.scrollTop);
  5. } else {
  6. console.log(document.body.scrollTop);
  7. }
  8. });

会在页面滚动时输出垂直方向上滚动的距离,而且适用于不同渲染模式。因为Safari 3.1之前不支持document.compatMode,所以早期版本会走第二个分支
类似于resize, scroll事件也会随着文档滚动而重复触发,因此最好保持事件处理程序的代码尽可能简单.

17.4.2 焦点事件

焦点事件在页面元素获得或失去焦点时触发。
这些事件可以与document.hasFocus()和document.activeElement一起为开发者提供用户在页面中导航的信息。焦点事件有以下6种:
❑ blur:当元素失去焦点时触发。这个事件不冒泡,所有浏览器都支持。
❑ DOMFocusIn:当元素获得焦点时触发。这个事件是focus的冒泡版。Opera是唯一支持这个事件的主流浏览器。DOM3 Events废弃了DOMFocusIn,推荐focusin。
❑ DOMFocusOut:当元素失去焦点时触发。这个事件是blur的通用版。Opera是唯一支持这个事件的主流浏览器。DOM3 Events废弃了DOMFocusOut,推荐focusout。
❑ focus:当元素获得焦点时触发。这个事件不冒泡,所有浏览器都支持。
❑ focusin:当元素获得焦点时触发。这个事件是focus的冒泡版。
❑ focusout:当元素失去焦点时触发。这个事件是blur的通用版。
两个主要事件是focus和blur,它们最大的问题是不冒泡。这导致IE后来又增加了focusin和focusout, Opera又增加了DOMFocusIn和DOMFocusOut。IE新增的这两个事件已经被DOM3 Events标准化。
当焦点从页面中的一个元素移到另一个元素上时,会依次发生如下事件:
(1)focuscout在失去焦点的元素上触发。
(2)focusin在获得焦点的元素上触发。
(3)blur在失去焦点的元素上触发。
(4)DOMFocusOut在失去焦点的元素上触发。
(5)focus在获得焦点的元素上触发。
(6)DOMFocusIn在获得焦点的元素上触发。
其中,blur、DOMFocusOut和focusout的事件目标是失去焦点的元素,focus、DOMFocusIn和focusin的事件目标是获得焦点的元素。

17.4.3 鼠标和滚轮事件

DOM3 Events定义了9种鼠标事件:
❑ click:在用户单击鼠标主键(通常是左键)或按键盘回车键时触发。
❑ dblclick:在用户双击鼠标主键(通常是左键)时触发。
❑ mousedown:在用户按下任意鼠标键时触发。不能通过键盘触发。
❑ mouseenter:在用户把鼠标光标从元素外部移到元素内部时触发。不冒泡,也不会在光标经过后代元素时触发。
❑ mouseleave:在用户把鼠标光标从元素内部移到元素外部时触发。不冒泡,也不会在光标经过后代元素时触发。
❑ mousemove:在鼠标光标在元素上移动时反复触发。不能通过键盘触发。
❑ mouseout:在用户把鼠标光标从一个元素移到另一个元素上时触发。移到的元素可以是原始元素的外部元素,也可以是原始元素的子元素。不能通过键盘触发。
❑ mouseover:在用户把鼠标光标从元素外部移到元素内部时触发。不能通过键盘触发。
❑ mouseup:在用户释放鼠标键时触发。不能通过键盘触发。
页面中的所有元素都支持鼠标事件。除了mouseenter和mouseleave,所有鼠标事件都会冒泡,都可以被取消,而这会影响浏览器的默认行为。
由于事件之间存在关系,因此取消鼠标事件的默认行为也会影响其他事件。
鼠标事件还有一个名为滚轮事件的子类别。
滚轮事件只有一个事件mousewheel,反映的是鼠标滚轮或带滚轮的类似设备上滚轮的交互。

1.客户端坐标

鼠标事件都是在浏览器视口中的某个位置上发生的。这些信息被保存在event对象的clientX和clientY属性中。
这两个属性表示事件发生时鼠标光标在视口中的坐标,所有浏览器都支持。
image.png
可以通过下面的方式获取鼠标事件的客户端坐标:

  1. let div = document.getElementById('myDiv');
  2. div.addEventListener('click', (event) => {
  3. console.log(`客户端坐标:${event.clientX}, ${event.clientY}`);
  4. });

2.页面坐标

客户端坐标是事件发生时鼠标光标在客户端视口中的坐标;
页面坐标是事件发生时鼠标光标在页面上的坐标。
通过event对象的pageX和pageY可获取。
这两个属性表示鼠标光标在页面上的位置,因此反映的是光标到页面(而非视口)左边与上边的距离。
在页面没有滚动时,pageX和pageY与clientX和clientY的值相同。

3.屏幕坐标

鼠标事件不仅是在浏览器窗口中发生的,也是在整个屏幕上发生的。
可通过event对象的screenX和screenY属性获取鼠标光标在屏幕上的坐标
image.png

4.修饰键

虽然鼠标事件主要是通过鼠标触发的,但有时候要确定用户想实现的操作,还要考虑键盘按键的状态。
键盘上的修饰键Shift、Ctrl、Alt和Meta经常用于修改鼠标事件的行为。
DOM规定了4个属性来表示这几个修饰键的状态:shiftKey、ctrlKey、altKey和metaKey。
(通过event对象)
这几属性会在各自对应的修饰键被按下时包含布尔值true,没有被按下时包含false。
在鼠标事件发生的,可以通过这几个属性来检测修饰键是否被按下。

5.相关元素

DOM通过event对象的relatedTarget属性,提供了相关元素的信息。
这个属性只有在mouseover和mouseout事件发生时才包含值,其他所有事件的这个属性的值都是null。
(通过event对象可拿到toElement, fromElement等)

6.鼠标按键

只有在元素上单击鼠标主键(或按下键盘上的回车键)时click事件才会触发,因此按键信息并不是必需的。
对mousedown和mouseup事件来说,event对象上会有一个button属性,表示按下或释放的是哪个按键。
DOM为这个button属性定义了3个值:0表示鼠标主键、1表示鼠标中键(通常也是滚轮键)、2表示鼠标副键。
按照惯例,鼠标主键通常是左边的按键,副键通常是右边的按键。

7.额外事件信息

DOM2 Events规范在event对象上提供了detail属性,以给出关于事件的更多信息。
对鼠标事件来说,detail包含一个数值,表示在给定位置上发生了多少次单击。
单击相当于在同一个像素上发生一次mousedown紧跟一次mouseup。
detail的值从1开始,每次单击会加1。
如果鼠标在mousedown和mouseup之间移动了,则detail会重置为0。

8.mousewheel事件

mousewheel事件会在用户使用鼠标滚轮时触发,包括在垂直方向上任意滚动。
这个事件会在任何元素上触发,并(在IE8中)冒泡到document和(在所有现代浏览器中)window。
mousewheel事件的event对象包含鼠标事件的所有标准信息,此外还有一个名为wheelDelta的新属性。
当鼠标滚轮向前滚动时,wheelDelta每次都是+120;而当鼠标滚轮向后滚动时,wheelDelta每次都是-120
image.png
可以为页面上的任何元素或文档添加onmousewheel事件处理程序,以处理所有鼠标滚轮交互

  1. window.addEventListener('mousewheel', (event) => {
  2. console.log(event.wheelDelta);
  3. });

显示了鼠标滚轮事件触发时wheelDelta的值。多数情况下只需知道滚轮滚动的方向,而这通过wheelDelta值的符号就可以知道

9.触摸屏设备

iOS和Android等触摸屏设备的实现大相径庭,因为触摸屏通常不支持鼠标操作。
在为触摸屏设备开发时,要记住以下事项:
❑ 不支持dblclick事件。双击浏览器窗口可以放大,但没有办法覆盖这个行为。
❑ 单指点触屏幕上的可点击元素,会触发mousemove事件。如果操作会导致内容变化,则不会再触发其他事件。如果屏幕上没有变化,则会相继触发mousedown、mouseup和click事件。点触不可点击的元素不会触发事件。可点击元素是指,点击时有默认动作的元素(如链接)或指定了onclick事件处理程序的元素。
❑ mousemove事件也会触发mouseover和mouseout事件。
❑ 双指点触屏幕并滑动导致页面滚动时,会触发mousewheel和scroll事件。

10.无障碍问题

建议不要使用click事件之外的其他鼠标事件向用户提示功能或触发代码执行。建议:
❑ 使用click事件执行代码。有人认为,当使用onmousedown执行代码时,应用程序会运行得更快。对视力正常用户来说确实如此。但在屏幕阅读器上,这样会导致代码无法执行,这是因为屏幕阅读器无法触发mousedown事件。❑ 不要使用mouseover向用户显示新选项。同样,原因是屏幕阅读器无法触发mousedown事件。如果必须要通过这种方式显示新选项,那么可以考虑显示相同信息的键盘快捷键。
❑ 不要使用dblclick执行重要的操作,这是因为键盘不能触发这个事件。
注:要了解更多关于网站无障碍的信息,可以参考WebAIM网站。

17.4.4 键盘与输入事件

键盘事件包含3个事件:
❑ keydown,用户按下键盘上某个键时触发,而且持续按住会重复触发。
❑ keypress,用户按下键盘上某个键并产生字符时触发,而且持续按住会重复触发。Esc键也会触发这个事件。DOM3 Events废弃了keypress事件,而推荐textInput事件。
❑ keyup,用户释放键盘上某个键时触发。
虽然所有元素都支持这些事件,但当用户在文本框中输入内容时最容易看到。
输入事件只有一个,即textInput。
这个事件是对keypress事件的扩展,用于在文本显示给用户之前更方便地截获文本输入。
textInput会在文本被插入到文本框之前触发。
当用户按下键盘上的某个字符键时,首先会触发keydown事件,然后触发keypress事件,最后触发keyup事件。
注:这里keydown和keypress事件会在文本框出现变化之前触发,keyup事件会在文本框出现变化之后触发。
如果一个字符键被按住不放,keydown和keypress就会重复触发,直到这个键被释放。
对于非字符键,在键盘上按一下这个键,会先触发keydown事件,然后触发keyup事件。
如果按住某个非字符键不放,则会重复触发keydown事件,直到这个键被释放,此时会触发keyup事件。

1.键码

对于keydown和keyup事件,event对象的keyCode属性中会保存一个键码,对应键盘上特定的一个键。
对于字母和数字键,keyCode的值与小写字母和数字的ASCII编码一致。
比如数字7键的keyCode为55,而字母A键的keyCode为65,而且跟是否按了Shift键无关。
image.png

2.字符编码

浏览器在event对象上支持charCode属性。
只有发生keypress事件时这个属性才会被设置值,包含的是按键字符对应的ASCII编码。
通常,charCode属性的值是0,在keypress事件发生时则是对应按键的键码。
IE8及更早版本和Opera使用keyCode传达字符的ASCII编码。要以跨浏览器方式获取字符编码,首先要检查charCode属性是否有值,如果没有再使用keyCode
一旦有了字母编码,就可以使用String.fromCharCode()方法将其转换为实际的字符了

3.DOM3的变化

尽管所有浏览器都实现了某种形式的键盘事件,DOM3 Events还是做了一些修改。
比如:
① DOM3 Events规范并未规定charCode属性,而是定义了key和char两个新属性。
其中,key属性用于替代keyCode,且包含字符串。在按下字符键时,key的值等于文本字符(如“k”或“M”);
在按下非字符键时,key的值是键名(如“Shift”或“ArrowDown”)。
char属性在按下字符键时与key类似,在按下非字符键时为null。
② DOM3 Events也支持一个名为location的属性,该属性是一个数值,表示是在哪里按的键。
可能的值为:0是默认键,1是左边(如左边的Alt键),2是右边(如右边的Shift键),3是数字键盘,4是移动设备(即虚拟键盘),5是游戏手柄(如任天堂Wii控制器)
与key属性类似,location属性也没有得到广泛支持,因此不建议在跨浏览器开发时使用。
③ 给event对象增加了getModiferState()方法。
这个方法接收一个参数,一个等于Shift、Control、Alt、AltGraph或Meta的字符串,表示要检测的修饰键。
如果给定的修饰键处于激活状态(键被按住),则方法返回true,否则返回false

4.textInput事件

DOM3 Events规范增加了一个名为textInput的事件,其在字符被输入到可编辑区域时触发。
作为对keypress的替代,textInput事件的行为有些不一样。
① keypress会在任何可以获得焦点的元素上触发,而textInput只在可编辑区域上触发。
② textInput只在有新字符被插入时才会触发,而keypress对任何可能影响文本的键都会触发(包括退格键)。
因为textInput事件主要关注字符,所以在event对象上提供了一个data属性,包含要插入的字符(不是字符编码)。
data的值始终是要被插入的字符。
因此如果在按S键时没有按Shift键,data的值就是”s”,但在按S键时同时按Shift键,data的值则是”S”。
event对象上还有一个名为inputMethod的属性,该属性表示向控件中输入文本的手段。
可能的值如下:
❑ 0,表示浏览器不能确定是什么输入手段;
❑ 1,表示键盘;
❑ 2,表示粘贴;
❑ 3,表示拖放操作;
❑ 4,表示IME;
❑ 5,表示表单选项;
❑ 6,表示手写(如使用手写笔);
❑ 7,表示语音;
❑ 8,表示组合方式;
❑ 9,表示脚本。
使用这些属性,可以确定用户是如何将文本输入到控件中的,从而可以辅助验证。

5.设备上的键盘事件

任天堂Wii会在用户按下Wii遥控器上的键时触发键盘事件。
虽然不能访问Wii遥控器上所有的键,但其中一些键可以触发键盘事件。

17.4.5 合成事件

合成事件是DOM3 Events中新增的,用于处理通常使用IME输入时的复杂输入序列。
IME可以让用户输入物理键盘上没有的字符。
例如,使用拉丁字母键盘的用户还可以使用IME输入日文。
IME通常需要同时按下多个键才能输入一个字符。合成事件用于检测和控制这种输入。
合成事件有以下3种:
❑ compositionstart,在IME的文本合成系统打开时触发,表示输入即将开始;
❑ compositionupdate,在新字符插入输入字段时触发;
❑ compositionend,在IME的文本合成系统关闭时触发,表示恢复正常键盘输入。
合成事件在很多方面与输入事件很类似。在合成事件触发时,事件目标是接收文本的输入字段。唯一增加的事件属性是data,其中包含的值视情况而异:
❑ 在compositionstart事件中,包含正在编辑的文本(例如,已经选择了文本但还没替换);
❑ 在compositionupdate事件中,包含要插入的新字符;
❑ 在compositionend事件中,包含本次合成过程中输入的全部内容。
与文本事件类似,合成事件可以用来在必要时过滤输入内容

17.4.6 变化事件

DOM2的变化事件(Mutation Events)是为了在DOM发生变化时提供通知。
注:这些事件已经被废弃,变化事件已经被Mutation Observers所取代

17.4.7 HTML5事件

DOM规范并未涵盖浏览器都支持的所有事件。很多浏览器根据特定的用户需求或使用场景实现了自定义事件。HTML5详尽地列出了浏览器支持的所有事件。本节讨论HTML5中得到浏览器较好支持的一些事件。注意这些并不是浏览器支持的所有事件。

1.contextmenu事件

开发者面临的问题是:如何确定何时该显示上下文菜单(在Windows上是右击鼠标,在Mac上是Ctrl+单击),以及如何避免默认的上下文菜单起作用。
结果出现了contextmenu事件,以专门用于表示何时该显示上下文菜单,从而允许开发者取消默认的上下文菜单并提供自定义菜单。
contextmenu事件冒泡,因此只要给document指定一个事件处理程序,就可以处理页面上的所有同类事件。
事件目标是触发操作的元素。
这个事件在所有浏览器中都可以取消,在DOM合规的浏览器中使用event.preventDefault(),在IE8及更早版本中将event.returnValue设置为false。
contextmenu事件应该算一种鼠标事件,因此event对象上的很多属性都与光标位置有关。
通常,自定义的上下文菜单都是通过oncontextmenu事件处理程序触发显示,并通过onclick事件处理程序触发隐藏的。

  1. window.addEventListener('load', (event) => {
  2. let div = document.getElementById('myDiv');
  3. div.addEventListener('contextmenu', (event) => {
  4. event.preventDefault();
  5. let menu = document.getElementById('myMenu');
  6. menu.style.left = event.clientX + 'px';
  7. menu.style.top = event.clientY + 'px';
  8. menu.style.visibility = 'visible';
  9. });
  10. document.addEventListener('click', (event) => {
  11. document.getElementById('myMenu').style.visibility = 'hidden';
  12. })
  13. });

元素上指定了一个oncontextmenu事件处理程序。这个事件处理程序首先取消默认行,确保不会显示浏览器默认的上下文菜单。接着基于event对象的clientX和clientY属性把
    元素放到适当位置。最后一步通过将visibility属性设置为”visible”让自定义上下文菜单显示出来。另外,又给document添加了一个onclick事件处理程序,以便在单击事件发生时隐藏上下文菜单(系统上下文菜单就是这样隐藏的)。
    虽然这个例子很简单,但它是网页中所有自定义上下文菜单的基础。在这个简单例子的基础上,再添加一些CSS,上下文菜单就会更漂亮。

    2.beforeunload事件

    beforeunload事件会在window上触发,用意是给开发者提供阻止页面被卸载的机会。
    它会在页面即将从浏览器中卸载时触发,如果页面需要继续使用,则可以不被卸载。
    这个事件不能取消,否则就意味着可以把用户永久阻拦在一个页面上。
    相反,这个事件会向用户显示一个确认框,其中的消息表明浏览器即将卸载页面,并请用户确认是希望关闭页面,还是继续留在页面上。
    为了显示这个确认框,需要将event.returnValue设置为:要在确认框中显示的字符串(对于IE和Firefox来说),并将其作为函数值返回(对于Safari和Chrome来说)
    image.png

    1. window.addEventListener('beforeunloaded', (event) => {
    2. let message = "I'm really going to miss you if you go.";
    3. event.returnValue = message;
    4. return message;
    5. });

    3.DOMContentLoaded事件

    window的load事件会在页面完全加载后触发,因为要等待很多外部资源加载完成,所以会花费较长时间。
    而DOMContentLoaded事件会在DOM树构建完成后立即触发,而不用等待图片、JavaScript文件、CSS文件或其他资源加载完成。
    相对于load事件,DOMContentLoaded可以让开发者在外部资源下载的同时就能指定事件处理程序,从而让用户能够更快地与页面交互。
    要处理DOMContentLoaded事件,需给document或window添加事件处理程序(实际的事件目标是document,但会冒泡到window)

    4.readystatechange事件

    旨在提供文档或元素加载状态的信息,但行为有时候并不稳定。
    支持readystatechange事件的每个对象都有一个readyState属性,该属性具有一个以下列出的可能的字符串值:
    ❑ uninitialized:对象存在并尚未初始化。
    ❑ loading:对象正在加载数据。
    ❑ loaded:对象已经加载完数据。
    ❑ interactive:对象可以交互,但尚未加载完成。
    ❑ complete:对象加载完成。

    5.pageshow与pagehide事件

    Firefox和Opera开发了一个名为往返缓存(bfcache, back-forward cache)的功能,此功能旨在使用浏览器“前进”和“后退”按钮时加快页面之间的切换。
    这个缓存不仅存储页面数据,也存储DOM和JavaScript状态,实际上是把整个页面都保存在内存里。
    如果页面在缓存中,那么导航到这个页面时就不会触发load事件。
    通常,这不会导致什么问题,因为整个页面状态都被保存起来了。
    不过,Firefx决定提供一些事件,把往返缓存的行为暴露出来。
    第一个事件是pageshow,其会在页面显示时触发,无论是否来自往返缓存。
    在新加载的页面上,pageshow会在load事件之后触发;在来自往返缓存的页面上,pageshow会在页面状态完全恢复后触发。
    注:虽然这个事件的目标是document,但事件处理程序必须添加到window上。
    除了常用的属性,pageshow的event对象中还包含一个名为persisted的属性。是一个布尔值,如果页面存储在了往返缓存中就是true,否则就是false
    pagehide,这个事件会在页面从浏览器中卸载后,在unload事件之前触发。
    与pageshow事件一样,pagehide事件同样是在document上触发,但事件处理程序必须被添加到window
    event对象中同样包含persisted属性,但用法稍有不同。
    对pagehide事件来说,persisted为true表示页面在卸载之后会被保存在往返缓存中。因此,第一次触发pageshow事件时persisted始终是false,而第一次触发pagehide事件时persisted始终是true

    6.hashchange事件

    用于在URL散列值(URL最后#后面的部分)发生变化时通知开发者。
    因为开发者经常在Ajax应用程序中使用URL散列值存储状态信息或路由导航信息。
    onhashchange事件处理程序必须添加给window,每次URL散列值发生变化时会调用它。
    event对象有两个新属性:oldURL和newURL。这两个属性分别保存变化前后的URL,而且是包含散列值的完整URL
    如果想确定当前的散列值,最好使用location对象

    1. window.addEventListener('haschange', (event) => {
    2. console.log(`Current hash: &{loaction.hash}`);
    3. });

    17.4.8 设备事件

    设备事件可以用于确定用户使用设备的方式。

    1.orientationchange事件

    苹果公司在移动Safari浏览器上创造了orientationchange事件,以方便开发者判断用户的设备是处于垂直模式还是水平模式。
    移动Safari在window上暴露了window.orientation属性,它有以下3种值之一:
    0表示垂直模式,90表示左转水平模式(主屏幕键在右侧), -90表示右转水平模式(主屏幕键在左)。
    虽然相关文档也提及设备倒置后的值为180,但设备本身至今还不支持。
    每当用户旋转设备改变了模式,就会触发orientationchange事件。但event对象上没有暴露任何有用的信息,这是因为相关信息都可以从window.orientation属性中获取

    2.deviceorientation事件

    deviceorientation是DeviceOrientationEvent规范定义的事件。
    如果可以获取设备的加速计信息,而且数据发生了变化,这个事件就会在window上触发。
    要注意的是,deviceorientation事件只反映设备在空间中的朝向,而不涉及移动相关的信息。
    设备本身处于3D空间即拥有x轴、y轴和z轴的坐标系中。
    如果把设备静止放在水平的表面上,那么三轴的值均为0,其中,x轴方向为从设备左侧到右侧,y轴方向为从设备底部到上部,z轴方向为从设备背面到正面

    17.4.9 触摸及手势事件

    本节介绍的事件只适用于触屏设备:

    1.触摸事件

    触摸事件有如下几种:
    ❑ touchstart:手指放到屏幕上时触发(即使有一个手指已经放在了屏幕上)。
    ❑ touchmove:手指在屏幕上滑动时连续触发。在这个事件中调用preventDefault()可以阻止滚动。
    ❑ touchend:手指从屏幕上移开时触发。
    ❑ touchcancel:系统停止跟踪触摸时触发。文档中并未明确什么情况下停止跟踪。
    这些事件都会冒泡,也都可以被取消。
    尽管触摸事件不属于DOM规范,但浏览器仍然以兼容DOM的方式实现了它们。
    因此,每个触摸事件的event对象都提供了鼠标事件的公共属性:bubbles、cancelable、view、clientX、clientY、screenX、screenY、detail、altKey、shiftKey、ctrlKey和metaKey。
    除了这些公共的DOM属性,触摸事件还提供了以下3个属性用于跟踪触点:
    ❑ touches: Touch对象的数组,表示当前屏幕上的每个触点。
    ❑ targetTouches: Touch对象的数组,表示特定于事件目标的触点。
    ❑ changedTouches: Touch对象的数组,表示自上次用户动作之后变化的触点。每个Touch对象都包含下列属性。❑ clientX:触点在视口中的x坐标。
    ❑ clientY:触点在视口中的y坐标。
    ❑ identifer:触点ID。
    ❑ pageX:触点在页面上的x坐标。
    ❑ pageY:触点在页面上的y坐标。
    ❑ screenX:触点在屏幕上的x坐标。
    ❑ screenY:触点在屏幕上的y坐标。
    ❑ target:触摸事件的事件目标。
    这些属性可用于追踪屏幕上的触摸轨迹。

    2.手势事件

    手势事件会在两个手指触碰屏幕且相对距离或旋转角度变化时触发。
    手势事件有以下3种:
    ❑ gesturestart:一个手指已经放在屏幕上,再把另一个手指放到屏幕上时触发。
    ❑ gesturechange:任何一个手指在屏幕上的位置发生变化时触发。
    ❑ gestureend:其中一个手指离开屏幕时触发。
    只有在两个手指同时接触事件接收者时,这些事件才会触发。
    在一个元素上设置事件处理程序,意味着两个手指必须都在元素边界以内才能触发手势事件(这个元素就是事件目标)。
    因为这些事件会冒泡,所以也可以把事件处理程序放到文档级别,从而可以处理所有手势事件。
    使用这种方式时,事件的目标就是两个手指均位于其边界内的元素。
    与触摸事件类似,每个手势事件的event对象都包含所有标准的鼠标事件属性:bubbles、cancelable、view、clientX、clientY、screenX、screenY、detail、altKey、shiftKey、ctrlKey和metaKey。
    新增的两个event对象属性是rotation和scale。
    rotation属性表示手指变化旋转的度数,负值表示逆时针旋转,正值表示顺时针旋转(从0开始);
    scale属性表示两指之间距离变化(对捏)的程度。开始时为1,然后随着距离增大或缩小相应地增大或缩小。

    17.4.10 事件参考

    本节给出了DOM规范、HTML5规范,以及概述事件行为的其他当前已发布规范中定义的所有浏览器事件。
    这些事件按照API和/或规范分类。
    注:只包含带厂商前缀事件的规范不在本参考中。
    image.png
    等等等等…