17.4.1 用户界面事件1.load事件2.unload事件3.resize事件4.scroll事件17.4.2 焦点事件17.4.3 鼠标和滚轮事件1.客户端坐标2.页面坐标3.屏幕坐标4.修饰键5.相关元素6.鼠标按键7.额外事件信息8.mousewheel事件9.触摸屏设备10.无障碍问题17.4.4 键盘与输入事件1.键码2.字符编码3.DOM3的变化4.textInput事件5.设备上的键盘事件17.4.5 合成事件17.4.6 变化事件17.4.7 HTML5事件1.contextmenu事件2.beforeunload事件3.DOMContentLoaded事件4.readystatechange事件5.pageshow与pagehide事件6.hashchange事件17.4.8 设备事件1.orientationchange事件2.deviceorientation事件17.4.9 触摸及手势事件1.触摸事件2.手势事件17.4.10 事件参考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上当页面加载完成后触发,在窗套()上当所有窗格()都加载完成后触发,在元素上当图片加载完成后触发,在元素上当相应对象加载完成后触发。❑ unload:在window上当页面完全卸载后触发,在窗套上当所有窗格都卸载完成后触发,在元素上当相应对象卸载完成后触发。❑ abort:在元素上当相应对象加载完成前被用户提前终止下载时触发。❑ error:在window上当JavaScript报错时触发,在元素上当无法加载指定图片时触发,在元素上当无法加载相应对象时触发,在窗套上当一个或多个窗格无法完成加载时触发。❑ select:在文本框(或textarea)上当用户选择了一个或多个字符时触发。❑ resize:在window或窗格上当窗口或窗格被缩放时触发。❑ scroll:当用户滚动包含滚动条的元素时在元素上触发。 1.load事件在window对象上,load事件会在整个页面(包括所有外部资源如图片、JavaScript文件和CSS文件)加载完成后触发。可通过两种方式指定load事件处理程序:第一种是JavaScript方式;第二种指定load事件处理程序的方式是向元素添加onload属性; // 使用addEventListener()方法来指定事件处理程序window.addEventListener('load', (event) => { console.log('Loaded!');});<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属性; window.addEventListener('unload', (event) => { console.log('Unloaded!');});<body onunload="console.log('Unloaded!')"></body> unload事件是在页面卸载完成后触发的,所以不能使用页面加载后才有的对象。此时要访问DOM或修改页面外观都会导致错误。注:根据DOM2 Events, unload事件应该在而非window上触发。但为了向后兼容,所有浏览器都在window上实现了unload事件。 3.resize事件当浏览器窗口被缩放到新高度或宽度时,会触发resize事件。这个事件在window上触发,因此可以通过JavaScript在window上,或者为元素添加onresize属性来指定事件处理程序。优先使用JavaScript方式。 window.addEventListener('resize', (event) => { console.log('Resized!');}); 不同浏览器在决定何时触发resize事件上存在重要差异。IE、Safari、Chrome和Opera会在窗口缩放超过1像素时触发resize事件,然后随着用户缩放浏览器窗口不断触发。Firefox早期版本则只在用户停止缩放浏览器窗口时触发resize事件。无论如何,都应该避免在这个事件处理程序中执行过多计算。否则可能由于执行过于频繁而导致浏览器响应明确变慢。注:浏览器窗口在最大化和最小化时也会触发resize事件。 4.scroll事件虽然scroll事件发生在window上,但实际上反映的是页面中相应元素的变化。在混杂模式下,可以通过元素检测scrollLeft和scrollTop属性的变化;在标准模式下,这些变化在除早期版的Safari之外的所有浏览器中都发生在元素上(早期版的Safari在上跟踪滚动位置) // 处理这些差异window.addEventListener('scroll', (event) => { if (document.compatMode == 'CSS1Compat') { console.log(document.documentElement.scrollTop); } else { console.log(document.body.scrollTop); }}); 会在页面滚动时输出垂直方向上滚动的距离,而且适用于不同渲染模式。因为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属性中。这两个属性表示事件发生时鼠标光标在视口中的坐标,所有浏览器都支持。可以通过下面的方式获取鼠标事件的客户端坐标: let div = document.getElementById('myDiv');div.addEventListener('click', (event) => { console.log(`客户端坐标:${event.clientX}, ${event.clientY}`);}); 2.页面坐标客户端坐标是事件发生时鼠标光标在客户端视口中的坐标;页面坐标是事件发生时鼠标光标在页面上的坐标。通过event对象的pageX和pageY可获取。这两个属性表示鼠标光标在页面上的位置,因此反映的是光标到页面(而非视口)左边与上边的距离。在页面没有滚动时,pageX和pageY与clientX和clientY的值相同。 3.屏幕坐标鼠标事件不仅是在浏览器窗口中发生的,也是在整个屏幕上发生的。可通过event对象的screenX和screenY属性获取鼠标光标在屏幕上的坐标 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可以为页面上的任何元素或文档添加onmousewheel事件处理程序,以处理所有鼠标滚轮交互 window.addEventListener('mousewheel', (event) => { console.log(event.wheelDelta);}); 显示了鼠标滚轮事件触发时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键无关。 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事件处理程序触发隐藏的。 window.addEventListener('load', (event) => { let div = document.getElementById('myDiv'); div.addEventListener('contextmenu', (event) => { event.preventDefault(); let menu = document.getElementById('myMenu'); menu.style.left = event.clientX + 'px'; menu.style.top = event.clientY + 'px'; menu.style.visibility = 'visible'; }); document.addEventListener('click', (event) => { document.getElementById('myMenu').style.visibility = 'hidden'; })}); 在元素上指定了一个oncontextmenu事件处理程序。这个事件处理程序首先取消默认行,确保不会显示浏览器默认的上下文菜单。接着基于event对象的clientX和clientY属性把元素放到适当位置。最后一步通过将visibility属性设置为”visible”让自定义上下文菜单显示出来。另外,又给document添加了一个onclick事件处理程序,以便在单击事件发生时隐藏上下文菜单(系统上下文菜单就是这样隐藏的)。虽然这个例子很简单,但它是网页中所有自定义上下文菜单的基础。在这个简单例子的基础上,再添加一些CSS,上下文菜单就会更漂亮。 2.beforeunload事件beforeunload事件会在window上触发,用意是给开发者提供阻止页面被卸载的机会。它会在页面即将从浏览器中卸载时触发,如果页面需要继续使用,则可以不被卸载。这个事件不能取消,否则就意味着可以把用户永久阻拦在一个页面上。相反,这个事件会向用户显示一个确认框,其中的消息表明浏览器即将卸载页面,并请用户确认是希望关闭页面,还是继续留在页面上。为了显示这个确认框,需要将event.returnValue设置为:要在确认框中显示的字符串(对于IE和Firefox来说),并将其作为函数值返回(对于Safari和Chrome来说) window.addEventListener('beforeunloaded', (event) => { let message = "I'm really going to miss you if you go."; event.returnValue = message; return message;}); 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,否则就是falsepagehide,这个事件会在页面从浏览器中卸载后,在unload事件之前触发。与pageshow事件一样,pagehide事件同样是在document上触发,但事件处理程序必须被添加到windowevent对象中同样包含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对象 window.addEventListener('haschange', (event) => { console.log(`Current hash: &{loaction.hash}`);}); 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和/或规范分类。注:只包含带厂商前缀事件的规范不在本参考中。等等等等…