Javascript高级程序设计(笔记)–13章

事件

使用侦听器(或处理程序)来预订事件, 以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察员模式的模型

DOM2级事件

1.ie8及以前除外所有浏览器均已支持

2.dom2事件并没有包含所有事件类型+Bom事件===》dom3级事件事件增强

事件流

1.事件流描述的是从页面中接收事件的顺序

2.IE 的事件流是事件冒泡流,而 Netscape Communicator 的事件流是事件捕获流

事件冒泡

定义: 即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点 接收,然后逐级向上传播到较为不具体的节点(文档)–由内到外

浏览器支持:所有现代浏览器都支持事件冒泡

浏览器差异: IE5.5 及更早版本中的事件冒泡 会跳过<html>元素,从body直接跳到document

IE9、Firefox、Chrome 和 Safari 则将事件一直冒泡到 window 对象

事件捕获

定义: 事件捕获的思想是不太具体的节点应该更早接收到事件而最具体的节点应该最后接收到事件–由外到内

DOM事件流

“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段

注意:1.DOM2级事件要求事件捕获阶段从document->body ,下一阶段为“处于目标”阶段,当事件发生后再处理事件中被看成是冒泡阶段的一部分,然后冒泡阶段发生

2.但 IE9、Safari、Chrome、Firefox 和 Opera 9.5 及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两个机会在目标对象上面操作事件

事件处理程序

事件:点击事件,load,mouse事件,用户或浏览器自身执行的某种动作

事件处理程序:响应某个事件的函数–名字以 “on” 开头(onclick,onload)

关联:为事件指定事件处理 程序

事件处理程序(事件侦听器)

事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码

event:局部变量 event事件对象

this:值等于事件目标元素

其作用域的扩展

function(){
  with(document){
    with(this){
     //元素属性值
  }
}

<form method="post">
<input type="text" name="username" value="">
<input type="button" value="Echo Username" onclick="alert(username.value)">
</form> //单击按钮显示userName

with:的使用请参考——https://www.jb51.net/article/12326.htm

假设 showMessage() 函数是在按钮下方、页面的最底部定义的。如果用户在页面解析 showMessage()函数之前就单击了按钮,就会引发错误。为此,很多 HTML 事件处理程序都会被封装在一个 try-catch 块中,以便错误不会浮出水面

<input type="button" value="Click Me" onclick="try{showMessage();}catch(ex){}">

DOM0 级事件处理程序

要使用 JavaScript 指定事件处理程序

var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert(this.id); //"myBtn"
}

注意

  • 这些代码运行时才会指定事件处理程序–所以如果按钮先显示,有可能在一定时间内点击无响应
  • DOM0 级方法指定的事件处理程序被认为是元素的方法,这时候的事件处理程序是在 元素的作用域中运行(程序中的 this 引用当前元素
  • 以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理

DOM2 级事件处理程序

addEventListener()和 removeEventListener()

注意

  • 第三个参数,Boolean:true(处于捕获阶段触发),false(默认,处于冒泡阶段触发)
  • 可以添加多个事件处理程序(两个click事件都可以执行)
  • 只能使用 removeEventListener() 来移除,且参数要相同
  • 兼容:ie9+

推荐使用冒泡阶段,捕获阶段只推荐在需要事件到达目标之前截获它的时候使用

IE事件处理程序

attachEvent() 和 detachEvent()

注意

  • ie8以下使用
  • 由于 IE8 及更早版本只支持事件冒泡所以事件只会被添加到冒泡阶段
  • 与上不同的是第一个参数为:onClick(上为click)
  • 作用域与上不同:全局作用域中运行(this===window)
  • 可以添加多个事件处理程序(两个click事件都可以执行但执行顺序相反)
  • 兼容ie&opera

事件对象

:在触发 DOM 上的某个事件时,会产生一个事件对象 even-包含着所有与事件有关的
信息

包括的信息有

  • 导致事件的元素
  • 事件的类型以及其他与特定事件相关的信息(1.鼠标事件中:鼠标位置的信息..2.键盘事件中:包含与按下的键有关的信息)
  • 只有在处理程序执行时event对象才存在,执行完成即被销毁

DOM中的事件对象

var btn = document.var btn = document.getElementB
属性/方法类型读写说明
bubblesBoolean是否冒泡
cancelableB是否可以取消事件的默认行为
currentTargetElement其事件处理程序当前正在处理事件的那个元素
target事件的目标
eventPhaseInteger当前事件所处阶段:1捕获阶段2处于目标上3冒泡阶段
defaultPreventedB为 true 表 示 已 经 调 用 了 preventDefault()
preventDefault()Function取消事件的默认行为。如果 cancelable 是
true则
可以调用此方法
stopImmediatePropagation()F取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调
stopPropagation()F取消事件的进一步捕获或冒泡。如果 bubbles为 true则可以调用此方法
trustedB为 true 表示事件是浏览器生成的。为 false 表事 件 是 由 开 发 人 员 通 过 JavaScript创 建 的(DOM3级事件中新增)
typeString被触发的事件的类型
viewAbstractView与事件关联的抽象视图。等同于发生事件的window 对象

注意

事件处理程序中的this,currentTarget,target的关系

  • 如果事件直接绑定到目标元素则三者值相同
  • 如果事件绑定到父节点(如document.body)值各不相同:this == event.currentTarget == document.body; event.target === 当前点击元素

IE中的事件对象

btn.onclick = function(){
var event = window.event;
alert(event.type); //"click"
} 

在IE中Dom0级事件绑定中event 对象作为 window 对象的一个属性存在

属性/方法类型读写说明
cancelBubbleBoolean默认为false,设置为true取消事件冒泡与(DOM中的stopPropagation方法相同)
returnValueB默认值为 true ,但将其设置为 false 就可以取消事件的默认行为(与DOM中的 preventDefault()方法相同)
srcElementElement事件目标 (与Dom中的target相同)
typeString事件类型

事件类型(DOM3)

  • UI事件:用户与页面的元素交互时触发
  • 焦点事件:当元素获得或失去焦点时触发
  • 鼠标事件:当用户通过鼠标在页面上执行操作时触发
  • 滚轮事件:当使用鼠标滚轮(或类似设备)时触发
  • 文本时间:当在文档中输入文本时触发
  • 键盘事件:用户通过键盘在页面上执行操作时触发
  • 合成时间:当为 IME(Input Method Editor,输入法编辑器)输入字符时触发
  • 变动(mutation)事件:当底层 DOM 结构发生变化时触发
  • 变动名称事件:当元素或属性名变动时触发。此类事件已经被废弃,没有浏览器实现他们
  • 还有一些非通用的由浏览器定制的专有事件

UI事件

ui事件名称定义兼容详解
DOMActivate元素被用户操作(通过鼠标或键盘)激活DOM3废弃,ff与Chrome支持
load1.当页面完全加载(img,js,css等外部资源都加载完成)后在 window 上面触发
2.当所有框架都加载完毕时在框架集上面触发
3.当图像加载完毕时在 元素上面触发 (图像不在DOM文档中指定了src也触发)
4.当嵌入的内容加载完毕时在混杂模式下<body>元素的scrollLeft与scrollTop监控变化,标准模式下除了safari都使用html反应变化
EventUtil.addHandler(window, “”scroll”, function(event){
if(document.compatMode == “CSS1Compat”){//标准模式
alert(document.documentElement.scrollTop);
//html元素变化
}
else{
alert(document.body.scrollTop)//body元素变化
}

注意:

  • 以上事件除了DomActive事件为ui事件外
  • 其他的均属于DOM2事件中的HTML事件–如何检测当前浏览器是否支持dom2
  • 一般来说,在 window 上面发生的任何事件都可以在<body>元素中通过相应的特性来指定,这只是为了保证向后兼容,建议使用js的方式
var isSupported = document.implementation.hasFeature("HTMLEvents", "2.0");//(前提此浏览器根据标准DOM2事件来实现这些事件则返回true)
var isSupported = document.implementation.hasFeature("UIEvent", "3.0");//同上

焦点事件

焦点事件名称定义兼容详解
blur在元素失去焦点时触发所有浏览器
DOMFocusIn在元素获得焦点时触发(与HTML 事件 focus 等价),但他冒泡只有Opera支持事件,DOM3废弃使用focusin
DOMFocusOut在元素失去焦点时触发与DOMfocusIn类似,DOM3使用focusout
focus在元素获得焦点时触发。这个事件不会冒泡所有浏览器
focusin在元素获得焦点时触发(与Html事件focus等价),支持冒泡IE5.5+、Safari 5.1+、Opera 11.5和Chrome
focusout 在元素失去焦点时触发(与Html事件blur等价),支持冒泡 IE5.5+、Safari 5.1+、Opera 11.5和Chrome

注意

  • 保证浏览器是否支持事件
var isSupported = document.implementation.hasFeature("FocusEvent", "3.0");//支持DOM3事件
  • focus与blur不支持冒泡,但在捕获阶段可以侦听

鼠标与滚轮事件

事件名称定义兼容详解
click在用户单击主鼠标按钮(一般是左边的按钮)或者按下回车键时触发
dbclick在用户双击主鼠标按钮(一般是左边的按钮)时触发DOM3事件
mousedown在用户按下了任意鼠标按钮时触发。不能通过键盘触发这个事件
mouseenter在鼠标光标从元素外部首次移动到元素范围之内时触发,这不冒泡 而且在光标移动到后代元素上不会触发(即在子元素后代元素上也算在当前范围内) IE、Firefox 9+和 Opera 支持这个事件
DOM3
mouseleave在位于元素上方的鼠标光标移动到元素范围之外时触发。这个事件不冒泡而且在光标移动到后代元素上不会触发(即在子元素后代元素上也算在当前范围内) DOM3
同上
mousemove当鼠标指针在元素内部移动时重复地触发
mouseout在鼠标指针位于一个元素上方,然后用户将其移入另一个元素(另一个元素可以是父/子元素)时触发
mouseover在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边内时触发
mouseup在用户释放鼠标按钮时触发。不能通过键盘触发这个事件
mousewheel这个事件可以在任何元素上面触发,会冒泡到 document (IE8)或 window (IE9、Opera、Chrome 及safary)对象上
DOMMouseScroll于mouseWheel类似event.detail返回滚轮以3位倍数的值 FireFox 特有

注意

  • 除了 mouseenter 和 mouseleave ,所有鼠标事件都会冒泡也可以被取消,取消鼠标事件将会影响浏览器的默认行为
  • 取消鼠标事件的默认行为还会影响其他事件,因为鼠标事件与其 他事件是密不可分的关系
  • 相继触发 mousedown 和 mouseup 事件,才会触发click事件,其中一个被取消click事件将不会触发
  • 只有触发两次click才会触发一次dbclick,间接取消mousedown/mouseup也将无法触发dbclick
  • 在触摸设备中
    • 不支持dbclick事件,双击放大此行为不可更改
    • 轻击可单击元素会触发mouseMove事件,如果会发生内容变化其他事件则不再发生如果屏幕内容未变,依次发生mousedown,mouseup,click,(可单击元素:有默认行为的如(a链接),或者指定了onclick事件的元素)
    • mousemove事件也会触发mouseover与mouseout事件
    • 两根手指在屏幕上滚动页面时会触发mousewheel与scroll事件
  • 无障碍性问题
    • 对于盲人或者屏幕阅读器使用者
    • 屏幕阅读器 无法触发mousedown事件和mouseover
    • 如果考虑无障碍别使用dbclick,键盘无法触发

鼠标事件的event

event对应的属性定义兼容详解
event.clientX/event.clientY
(客户区域位置)
相对于视口的鼠标位置
event.pageX/event.pageY
(页面区域位置)
相对于页面的鼠标位置 ie8+EventUtil.addHandler(div, “cli”click”, function(event){
event = EventUtil.getEvent(event);
var pageX = event.pageX,
pageY = event.pageY;
if (pageX === undefined){
pageX = event.clientX + (document.body.scrollLeft ||document.documentElement.scrollLeft);
}
if (pageY === undefined){
….同上scrollTop
}
})
event.screenX/event.screenY
屏幕坐标位置
还有一个相对于整个电脑屏幕的位置
Shift、Ctrl、Alt 和 Meta按键对应:shiftKey 、 ctrlKey 、 altKey 和metaKeyBoolean值:true为按下ie8以下不支持metaKey
relatedTarget只存在于mouseover/mouseoutie8以下不支持返回null
button鼠标按钮event:只存在于mousedown/mouseupie8以下返回的值不同Number:0主鼠标(左键)
1中间键2(右键)
detail在同一个元素上
相继地发生一次 mousedown 和一次mouseup算一次,如果在up期间移动了则清零
event.offsetX/event.offsetY光标相对于目标元素边界的 x 、y坐标IE特有
wheelDelta当用户向前滚动鼠标滚轮时:向前为+120的倍数,向后为-120的倍数opera < 9.5 以下版本数值相反(向前为负数–)

键盘与文本事件

事件名称定义兼容详解
keydown键盘按下任意键触发,不放则重复执行
keypress键盘按下字符键(包括esc)触发,不放则重复执行–按下的键会影响到屏幕中文本的显示(添加删除字符的按键)也会触发keypress事件safari3.1以下与keydwon完全一样
keyup当用户释放键盘上的键时触发
textInput文本插入文本框之前会触发 textInput 事件(对keypress事件的补充)ie9+

注意

  • 当按下一个按键时的流程
    • keydown //文本框变化之前触发 (按住任意键不放一直执行)
    • keypress //文本框变化之前触发(按住字符键不放一直执行)
    • textInput //文本插入文本框触发
    • keyup //文本框发生变化触发

event对象

event对象属性定义兼容详解
keyCode与键盘上一个特定的键对应值—ASCII 码中对应小写字母(与shift无关)或数字的编码相同
charCodekeypress事件中的event属性对应按键Ascll码ie9+不支持返回undefined//省略的代码
getCharCode: function(event){
if (typeof event.charCode == “number”){
return event.charCode;
}else{
return event.keyCode;
}
String.fromCharCode()//AScall转字符
keylocation/location表示按下了什么位置上的键(1左侧Alt….)DOM3-IE9支持location;Safari 和 Chrome 支持名为 keyLocation不推荐使用
getModifierState()//方法表示要检测的修改键(shift,control,alt,meta)是否是活动的,true活动的false不是只有ie9支持 不推荐使用
datatextInput事件专有:表示
inputMethodtextInput事件专有 :表示把文本输入到文本框中的方式ie9+,只有ie支持此属性0表示浏览器不确定是怎么输入的。
1,表示是使用键盘输入的
2,表示文本是粘贴进来的。…

设备中的键盘事件

  • 如:任天堂 Wii 遥控器出发键盘事件
  • iOS 版 Safari 和 Android 版 WebKit 在使用屏幕键盘时会触发键盘事件
  • keyup,keydown,keypress

复合事件

注意

  • 用于处理 IME(Input Method Editor,输入法编辑器,搜狗输入法) 的输入序列。
  • 使用拉丁文键盘的用户通过 IME 照样能输入日文字符
  • IME 通常需要同时按住多个键,但最终只输入一个字符
复合事件名称定义兼容详解
compositionstart在 IME 的文本复合系统打开时触发,表示要开始输入了DOM3才支持(ie9+)
compositionupdate在向输入字段中插入新字符时触发 DOM3才支持
compositionend在 IME 的文本复合系统关闭时触发,表示返回正常键盘输入状态 DOM3才支持
event对象属性定义兼容详解
data1. compositionstart –正在编辑的文本(如:被选中要被替换的文本)
2. compositionupdate –正在插入的新字符
3. compositionend –包含此次输入会话中插入的所有字符

变动事件

  • 能在 DOM中的某一部分发生变化时给出提示
  • 变动事件是为 XML或 HTML DOM设计的,并不特定于某种语言
  • DOM2级事件定义

事件名称

变动事件名称定义兼容详情
DOMSubtreeModified在 DOM 结构中发生任何变化时触发。这个事件在其他任何事件触发后都会触发ie9+才有这些事件-下同1.被移除/t添加节点的父节点上触发
2.事件冒泡
DOMNodeInserted在一个节点作为子节点被插入到另一个节点中时触发DOM2事件1.事件冒泡
2.当前节点上触发
3.插入后才执行
DOMNodeRemoved在节点从其父节点中被移除时触发1.事件会冒泡可以再任何DOM层次上处理它
2.事件发生时节点未从父节点删除,因此parentNode还指向父节点
DOMNodeInsertedIntoDocument在一个节点被直接插入文档或通过子树间接插入文档后触发1.不冒泡
2.发生在插入节点上
DOMNodeRemovedFromDocument这个事件在 DOMNodeRemoved 之后触发–节点移除出文档1.事件不会冒泡
2.所有子节点和被移除节点相机触发此事件
3.不会冒泡所有要绑定事件到对应的节点
DOMAttrModified特性被修改后触发
DOMCharacterDataModified在文本节点的值发生变化时触发

event事件对象

事件对象属性定义兼容详解
target删除节点触发DOMNodeRemoved–被删除节点
relatedNode删除节点触发DOMNodeRemoved–被删除节点父节点

HTML5事件

  • 用以详尽列出浏览器应该支持的所有事件
事件名称定义兼容详解
contextmenu单击鼠标右键可以调出上下文菜单,提供自定义的菜单IE、Firefox、Safari、Chrome 和 Opera11+1.冒泡
beforeunload在页面卸载前阻止这一操作–可以通过它来取消卸载并继续使用原有页面Opera 11 及之前的版本不支持 beforeunload,其他均支持1.必须将 event.returnValue 的值设置为要显示的字符串(ie和firfox),同时作为函数的值返回(对 Safari 和 Chrome 而言)
2.例子EventUtil.addHandler(window, “beforeunload”,function(event){
event = EventUtil.getEvent(event);
var message = “bye bye?”
event.returnValue = message;
return message;
})
DOMContentLoaded形成完整的 DOM树之后就会触发(不理会image,javascript 等资源是否加载完成)
2.始终会在load事件之前触发
IE9+、Firefox、Chrome、Safari 3.1
和 Opera 9+
1.document 或 window 添加相应的事件处理程序-他的实际目标是document
2.不支持的浏览器兼容使用
setTimeout(function(){
//其意义为:1.在当前 JavaScript 处理完成后立即运行这个函数
2.在页面下载和构建
期间,只有一个 JavaScript 处理过程,因此超时调用会在该过程结束时立即触发.
},0)
readystatechange1.与文档或元素的加载状态有关的信息
2.支持readystatechange事件的每个对象都
1.返回readyState属性
2.readyState 的这几个阶段并不是在所有对象中存在
3.如果在页面中包含较少外部资源的情况下,完成阶段先于交互阶段可能性很大,有必要同时检测交互和完成阶
pageshow1.firefox 和 Opera 有一个特性:往返缓存(bfcache)
2.这个缓存中不仅保存着页面数据,还保存了 DOM 和 JavaScript 的状态;实际上是将整个页面都保存在了内存里
3.产生缓存后点击前进后退按钮将不再触发load事件
4.绑定到window上,但事件目标为document
Firefox、Safari 5+、Chrome 和 Opera,IE9 及之前版
本不支持这两个事件
(function(){
var showCount = = 0;
EventUtil.addHandler(window, “load”, function(){
alert(“Load fired”);
})
EventUtil.addHandler(window
,”pageshow”,function(){
showCount++;
alert(“Show has been fired ” +
” times. Persisted? ” + event.persisted);});
})();
pagehide1.页面卸载时触发
2.unload 事件之前触发
hashChange以便在 URL 的参数列表(及 URL 中“#”号后面的所有字符串)发生变化时通知开发人员IE8+、Firefox 3.6+、Safari 5+、Chrome 和 Opera 10.6+

event事件对象

属性名定义兼容详解
uninitialized对象存在但尚未初始化
loading对象正在加载数据
loaded对象加载数据完成
interactive可以操作对象了,但还没有完全加载
complete对象已经加载完毕
persisted对于 pageshow事件,如果页面是从 bfcache 中加载的,那么 persisted 的值就是 true
对于 pagehide 事件页面在卸载之后会被保存在 bfcache 中,那么 persisted 的值也会被设置为 true
oldURL这两个属性分别保存着参数列表变化前后的完整 URL只有 Firefox 6+、Chrome 和 Opera 支持推荐使用location获取参数(兼容性)
newURL

注意

  • 基 于 元 素 触 发 的 readystatechange事件中即 readyState 属性无论等于 “loaded” 还

是 “complete” 都可以表示资源已经可用

  • 有时候, readyState 会停在 “loaded” 阶段而永远不会“完成”;有时候,又会跳过 “loaded” 阶段而直接“完成”
  • 同样的方式也适用于css的link加载
EventUtil.addHandler(window, ""load", function(){
 var script = document.createElement("script");
 EventUtil.addHandler(script, "readystatechange",  function(event){
 event = EventUtil.getEvent(event);
 var target = EventUtil.getTarget(event);
 if (target.readyState == "loaded" || target.readyState== "complete"){
  EventUtil.removeHandler(target, "readystatechange", arguments. callee);
  //移除事件绑定是为了避免二次出发(loaded一次,complate一次)
 alert("Script Loaded");
}
});
script.src = "example.js";
document.body.appendChild(script);

设备事件

W3C 从 2011年开始着手制定一份关于设备事件的新草

事件

事件定义兼容详解
orientationchange只要用户改变了设备的查看模式就会触发ios设备
MozOrientation当设备的加速计检测到设备方向改变时触发Firefox 3
带加速计的设备才支持 MozOrientation 事件.(使用)
x:x轴右边倾斜值减少
y:y用户正前方倾斜值减少
z:静止为1,移动设备值减少,失重为0
deviceorientation与上类似iOS 4.2+中的 Safari、Chrome 和 Android 版
WebKit
与 MozOrientation 的方向系统不同
1.x正方向向右
2.y正方向向上
3.z正方向面向用户
devicemotion这个事件是要告诉开发人员设备什么时候移动,而不仅仅是设备

检测到设备是不是正在
往下掉,或者是不是被走着的人拿在手里
iOS 4.2+中的 Safari、Chrome 和 Android 版
WebKit

属性

属性定义兼容详解
orientation(IOS)1.0 表示肖像模式
90 表示向左旋转的横向模式
-90 表示向右旋转的横向模
180 表示 iPhone 头朝下(未实现)
safari
event.x/y/z( MozOrientation )默认设备处于竖直状态:0,0,1
x:x轴右边倾斜值减少
y:y用户正前方倾斜值减少
z:静止为1,移动设备值减少,失重为0
alpha( deviceorientation ) 围绕 z轴旋转时(即左右旋转时)y 轴的度数差
介于 0 到 360 之间的浮点数
beta在围绕 x轴旋转时(即前后旋转时),z轴的度数差
介于-180到 180之间的浮点数
gamma
在围绕 y轴旋转时(即扭转设备时),z轴的度数差;
介于-90到 90之间的浮点数。
acceleration(devicemotion)

一个包含 x 、 y 和 z 属性的对象,在不考虑重力的情况告诉你在每个方向上的加速度
rotationRate包含表示方向的 alpha 、 beta 和 gamma

触摸与手势事件

触摸事件

事件名称定义兼容详解
touchstart手指触摸屏幕时触发
touchmovetouchmove :当手指在屏幕上滑动时连续地触发。在这个事件发生期间,调用 preventDefault()可以阻止滚动
touchend当手指从屏幕上移开时触发
touchcancel当系统停止跟踪触摸时触发,确切的触发事件文档中无说明
  • 以上事件都冒泡
  • 每个触摸事件的 event 对象都提供了在鼠标事件中常见的属性(bubbles,cancleable,clientX….)
event属性名称定义兼容详解
touches当前跟踪的触摸操作的 Touch 对象的数组
targetTouchs特定于事件目标的 Touch 对象的数组
changeTouches表示自上次触摸以来发生了什么改变的 Touch 对象的数组

手势事件

  • 只有两个手指都触摸到事件的接收容器时才会触发这些事件
  • 两个手指必须同时位于该元素的范围之内,才能触发手势事件
  • 事件冒泡
事件名称定义
gesturestart当一个手指已经按在屏幕上而另一个手指又触摸屏幕时触发
gesturechange当触摸屏幕的任何一个手指的位置发生变化时触发
gestureend任何一个手指从屏幕上面移开时触发
event属性名称(特有)详解
rotation手指变化引起的旋转角度负值表示逆时针旋转
正值表示顺时针旋转

触摸与手势事件的关系

  • 当一个手指放在屏幕上时,会触发 touchstart 事件
  • 另一个手指又放在了屏幕上,则会先触发 gesturestart事件
  • 随后触发基于该手指的 touchstart事件
  • 如果一个或两个手指在屏幕上滑动,将会触发 gesturechange事件
  • 但只要有一个手指移开,就会触发 gestureend 事件
  • 紧接着又会触发基于该手指的 touchend 事件

内存与性能

  • 添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能
  • 原因是多方面的
    • 每个函数都是对象,都会占用内存,内存中的对象越多,性能就越差
    • 必须事先指定所有事件处理程序而导致的 DOM访问次数,会延迟整个页面的交互就绪时间

事件委托

  • 如果委托到document上,在页面任何生命周期都可添加事件处理程序(无需等待 DOMContentLoaded 或 load 事),即只要元素呈现在页面上既可以使用
  • 设置事件处理程序所需的时间更少,只添加一个事件处理程序所需的 DOM引用更少
  • 整个页面占用的内存空间更少,能够提升整体性能
  • 事件需要支持冒泡

移除事件处理程序

  • 内存中留有那些过时不用的“空事件处理程序”(dangling event handler)也是造成 Web 应用程序内存与性能问题的主要原因(在两种情况下,可能会造成上述问题)
    • 文档中移除带有事件处理程序的元素时(removeChild,replaceChild,innerHtml替换)原来添加到元素中的事件处理程序极有可能无法被当作垃圾回收(尤其在ie中)
    • 就是卸载页面的时候,尤其是ie8及更早版本如果在页面被卸载之前没清理干净事件处理程序,那它们就会滞留在内存中,每次加载完页面再卸载页面时(可能是在两个页面间来回切换,也可以是单击了“刷新”按钮)内存中滞留的对象数目就会增加,因为事件处理程序占用的内存并没有被释放
  • 最好的做法是在页面卸载之前,先通过 onunload(此事件是bfcache不被触发,介意的话则只能在ie中使用此事件) 事件处理程序移除所有事件处理程序,事件委托技术再次表现出它的优势—需要跟踪的事件处理程序越少,移除它们就越容易

模拟事件

  • 在测试 Web 应用程序,模拟触发事件是一种极其有用的技术
  • DOM2 级规范为此规定了模拟特定事件的方式
  • E9、Opera、Firefox、Chrome 和 Safari 都支持这种方式,ie有他特有的方式

DOM中的事件模拟

  • 模拟事件-document.createEvent(),创建event对象参数为:事件类型
    • UIEvents :一般化的 UI 事件
    • MouseEvents :一般化的鼠标事件
    • MutationEvents :一般化的 DOM 变动事件
    • HTMLEvents :一般化的 HTML 事件
    • DOM3去掉事件的“s”–UIEvent
  • event事件初始化–
    • 使用与事件有关的信息对其进行初始化,每种类型的 event 对象都有一个特殊的方法,为方法传入适当的数据就可以初始化该 event 对象
    • 不同类型的这个方法的名也不同,取决于上一步的事件类型
  • 触发事件
    • dom.dispatchEvent(),参数:要触发事件的event对象,触发事件后,该事件就跻身“官方事件”之列了能够照样冒泡并引发相应事件处理程序的执行
var btn = document.getElementById("myBtn");
//创建事件对象
var event = document.createEvent("MouseEvents");
//初始化事件对象
event.initMouseEvent("click", true, true,  document.defaultView, 0, 0, 0, 0, 0,
false, false, false, false, 0,null);
//触发事件
btn.dispatchEvent(event);

自定义dom事件

  • 目的是让开发人员创建自己的事件
    • 可以调用 createEvent(“CustomEvent” )
    • 返回的对象有一个名为 initCustomEvent() 的方法
      • 初始化使用四个参数:
      • type (字符串):触发的事件类型,例如 “keydown
      • bubbles (布尔值):表示事件是否应该冒泡。
      • cancelable (布尔值):表示事件是否可以取消。
      • detail (对象):任意值,保存在 event 对象的 detail 属性中。
    • 定义好以后像分派其他事件一样在 DOM 中分派创建的自定义事件对象

DOM3.0级 浏览器支持:ie9&firefox6+

IE中的事件模拟

  • 在 IE8 及之前版本中模拟事件与在 DOM 中模拟事件的思
var btn = document.getElementById("myBtn");
//创建事件对象
var event = document.createEventObject();
//初始化事件对象
event.screenX = 100
event.screenY = 0;
event.clientX = 0;
event.clientY = 0;
...
//触发事件
btn.fireEvent("onclick", event);