JavaScript与HTML之间的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
1.事件流
事件流描述的是从页面中接收事件的顺序,IE的事件流是冒泡流,Netscape的事件流是事件捕获流。
1.1 事件冒泡
事件冒泡,即事件开始由最具体的元素接收,然后逐级向上传播至document对象。
1.2 事件捕获
事件捕获,document节点最先接收到事件,逐级向下,最具体的节点最后接收到事件。这么安排的用意是在事件到达预定目标前捕获它。
按照DOM2级事件规范要求事件捕获应从document对象开始传播,但实际上IE9、Safari、Chrome、Opera这几个主流浏览器是从window开始捕获事件。
1.3 DOM事件流
DOM2级事件规定事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
DOM2级事件规范要求捕获阶段不涉及事件目标,但IE9+、Safari、Firefox、Opera9.5+都会在捕获阶段触发事件对象上的事件,所以有2个机会在目标对象上操作事件。
2.事件处理程序
事件就是用户或浏览器自身执行的某种动作,响应事件的函数就叫做事件处理程序。
2.1 HTML事件处理程序
在HTML标签里写上事件属性,指定回调代码。
回调代码可以直接写js代码,也可以指定函数,只要是全局作用域中能访问得到的函数都行。
回调函数会接受到一个参数,就是事件对象event,是这个函数的局部变量。而且回调函数里的this指向事件目标元素。而且如果事件的目标元素是一个表单元素,this.form就是它所在的表单。
在这个回调函数里,document和this和this.form(如果有的话)也被压进了作用域链里,所以在回调函数里,document、this、this.form上的属性都能直接访问,像访问局部变量一样。不过作者又说,这个特性在不同浏览器中表现有所不同,不清楚具体情况,以后如果要用再查。
2.2 DOM0级事件处理程序
用js先取得一个要操作的对象的引用,给它的事件处理程序属性赋值(赋一个函数)。
因为DOM0级方法指定的事件处理程序被认为是元素的方法,所以被指定的程序是在元素的作用域中运行,所以程序中的this指向元素。
要删除通过DOM0级方法指定的事件处理程序,只要把元素的事件处理程序属性值赋为null即可。
2.3 DOM2级事件处理程序
addEventListener和removeEventListener就是DOM2级事件处理程序添加方法。所有DOM节点都包含这两个方法。它们接收3个参数:事件名、回调函数、布尔值(true表示在捕获阶段调用回调,false表示在冒泡阶段调用回调)。
跟DOM0级一样,DOM2级添加的事件处理程序也是在其元素的作用域中运行,所以函数里的this也是指向该元素,不同的是用DOM2级方法可以指定多个回调,并且会按照添加它们的顺序触发。还有,用DOM2级方法添加的回调只能用DOM2级方法删除,不能用DOM0级那种把属性值置为null的方法来删除。由于removeEventListener需要传入指定回调函数(一定要跟注册的时候传入的函数是同一个)才能删掉该回调,所以注册的时候要保留对该回调函数的引用,否则就不能取消回调了。
多数情况下,事件处理程序程序都是添加到冒泡阶段,这样兼容性比较好。所以如果不是需要在到达目标元素前截获事件,就不推荐把事件添加到捕获阶段。
小tip:IE9、Firefox、Safari、Chrome、Opera支持DOM2级事件处理程序
2.4 IE事件处理程序
IE的事件处理方法:attachEvent、detachEvent,跟DOM2的addEventListener和removeEventListener相似。
不同之处:attachEvent和detachEvent不需要传入布尔值,事件只能被添加到冒泡阶段;回调函数的作用域不同,DOM方法的回调是在元素的作用域中运行,attachEvent方法注册的回调是在全局作用域中运行,它的this指向window;IE方法也可以添加多个回调函数,但事件触发时,回调函数按添加时的顺序的逆序来触发,后添加的先执行。
相同之处:要删除回调必须传入跟注册时一样的回调函数,所以同样地,注册的时候最好保留回调函数的引用。
小tip:IE和Opera支持IE事件处理程序
2.5 跨浏览器的事件处理程序
介绍了一种自己编写事件添加/删除的方法,来兼容各种不同浏览器。(就是各种if else,把各种情况综合起来)
3.事件对象
DOM上触发事件时会产生一个事件对象,事件对象里包含很多信息。所有浏览器都支持event对象,但是细节上有所不同。
3.1 DOM中的事件对象
支持DOM事件处理程序的浏览器会给事件处理程序传入一个event对象。event对象有以下方法/属性:type事件类型、target事件的目标元素、currentTarget当前正在处理事件的元素(this始终等于currentTarget)、eventPhase调用回调时事件的阶段(1为捕获阶段 2为“处于目标” 3为冒泡阶段)、bubbles表示事件是否冒泡(布尔型)、cancelabel是否可以取消事件的默认行为(布尔型)、preventDefault取消事件的默认行为的方法、stopPropagation取消事件的继续捕获或冒泡的方法。(还有几个我没抄)
小tip:事件处理程序执行完毕后event对象会被销毁
3.2 IE中的事件对象
在IE中访问事件对象,如果是用DOM0级方法添加的事件处理程序(元素.事件名=某个回调函数)那么event对象会作为window对象的一个属性存在,可以以window.event这样的方式来访问;如果使用attachEvent方式添加的事件处理程序,那么event对象会被作为参数传入回调,同时也可以通过window.event访问;如果是在HTML代码上指定了事件处理程序,event局部变量就是event对象(跟其它浏览器一样)。
IE的event对象有以下属性/方法:cancelBubble(布尔值默认false,表示事件可以冒泡,设为true可以取消事件冒泡,相当于其它浏览器的stopPropagation方法)、returnValue(布尔值默认true,设为false可以取消事件的默认行为,相当于其它浏览器的preventDefault)、srcElement(相当于其它浏览器的target)、type(事件类型)
IE中,事件处理程序的作用域是根据指定它的方式来确定的(元素.事件属性=balabala这样才会运行在元素的作用域,attachEvent这样的写法回调函数会运行在全局),所以回调函数里的this不一定指向元素,用event.srcElement来引用目标元素更保险。
3.3 跨浏览器的事件对象
讲了怎么样自己编写代码来兼容不同浏览器,把获取事件对象、获取触发事件的元素、阻止元素默认行为、阻止事件传递这些操作写成统一的方法(这些方法里都是各种if else)
4.事件类型
DOM2级事件模块定义了一些事件类型,DOM3级事件模块在DOM2基础上重新定义并添加了一些事件模型。HTML5也定义了一组事件。还有些浏览器实现了一些DOM、BOM专有事件。总之,本章要介绍这些事件。
4.1 UI事件
UI事件指的是那些与不一定与用户操作有关的事件。
UI事件有这些:load、unload、abort、error、select、resize、scroll
load
页面完全加载后,会触发window对象的load事件。可以用js给window对象注册load事件处理程序,也可以在HTML的body标签上增加onload属性,其实window上的事件都可以在body标签上注册事件处理程序,但这是因为HTML访问不到window而生出的权宜之计,本书更推荐用js来注册window事件处理程序。
根据DOM2级事件规范,其实应该在document对象上触发load事件,而不是在window上,但所有浏览器为了向后兼容都实现了在window上触发。
图像上也可以触发load。如果你想创建一个img元素并为其指定一个onload事件处理程序,注意要先注册好回调,并添加到文档树,再指定src。因为img元素一被指定src马上就会开始加载。除了创建img元素,也可以创建Image对象(DOM0级),var xxx = new Image();xxx.addEventListener......;xxx.src = ......;
img元素的属性和方法Image对象都有,只是不能添加到DOM树而已。在DOM标准出来之前,开发人员经常用Image元素来预加载图像。
除了window和img,script元素也会触发load事件(在IE9+、Firefox、Opera、Chrome和Safari3+),但与img不同,script元素并不是指定src后就马上开始加载,而是需要“指定src”和“添加到文档树”两条都满足后才会开始加载。
IE和Opera支持link元素的load事件,以便开发人员确定样式表是否加载完毕,与script类似,它也是“指定src”和“添加到文档树”两条都满足后才会开始加载。
unload
在文档被完全卸载后触发。同样可以在window上注册事件处理程序,也可以在body标签上注册事件处理程序。编写回调函数时注意,页面加载后存在的那些对象此时并不一定存在,比如说在unload事件触发时进行DOM节点操作就会导致错误。
根据DOM2级事件规范,其实应该在document对象上触发unload事件,而不是在window上,但所有浏览器为了向后兼容都实现了在window上触发。
resize
可以在window对象上指定resize事件处理程序,也可以在body元素上指定onresize属性值。
不同浏览器的触发机制不同,Firefox在用户停止调整窗口大小时才会触发resize,而IE、Safari、Chrome、Opera会在窗口每变化1像素都触发一次resize。所以注意不要在resize事件处理程序中放些很消耗资源的代码,这样浏览器会因频繁触发resize而卡住。
scroll
scroll事件在window对象上发生,但实际上表示的是页面中相应元素的变化。
在混杂模式下,可以通过body元素的scrollLeft和scrollTop来获取页面滚动详情;在标准模式下,Safari浏览器会在body元素上反映滚动详情,其它浏览器会在HTML元素上反映滚动详情。(不知道什么是混杂模式和标准模式?)
4.2 焦点事件
焦点事件:blur(元素失去焦点时触发,不冒泡)、focus(元素获得焦点时触发,不冒泡)、focusin(元素获得焦点时触发,冒泡)、focusout(元素失去焦点时触发,冒泡)
当焦点从元素A转到元素B,以下事件依次触发:1.元素A触发focusout 2.元素B触发focusin 3.元素A触发blur 4.元素B触发focus
var isSupported = document.implementation.hasFeature("FocusEvent", "3.0");
可以检查浏览器是否支持这些事件。
小tip:虽然focus和blur不冒泡,事件捕获阶段也可以侦听到它们。
4.3 鼠标与滚轮事件
DOM3级事件模块中定义了9个鼠标事件:
①click单击或回车
②dblclick双击
③mousedown按下任意鼠标按钮,不能通过键盘触发
④mouseenter光标从元素外部移动到元素范围内,不冒泡,移入子元素不触发
⑤mouseleave光标从元素内部移动到元素外部,不冒泡,移出子元素不触发
⑥mousemove光标在元素内部移动,不能通过键盘触发
⑦mouseout光标从元素内部移出,移出子元素也会触发。不能通过键盘触发
⑧mouseover光标从元素外部移入,移入子元素也会触发。不能通过键盘触发
⑨mouseup在用户释放鼠标按钮时触发。不能通过键盘触发
页面上的所有元素都支持鼠标事件,除mouseenter和mouseleave,其它鼠标事件都会冒泡。
鼠标事件如果取消默认行为会影响到其它事件,比如mousedown和mouseup二者缺其一,click事件就不能触发,click如果不能触发dblclick也就不能触发。
在一次双击动作里,依次触发以下事件:mousedown,mouseup,click,mousedown,mouseup,click,dblclick
检测浏览器是否支持DOM2级鼠标事件(除dbcclick、mouseenter、mouseleave):var isSupported = document.implementation.hasFeature("MouseEvents", "2.0")
检测浏览器是否支持DOM3级鼠标事件:var isSupported = document.implementation.hasFeature("MouseEvent", "3.0")
此外还有滚轮事件,滚轮事件下只有一种:mousewheel,滚轮滚动事件
客户区坐标位置
鼠标事件的event对象有两个属性:clientX和clientY,是鼠标事件发生时,光标相对于浏览器视口的水平方向坐标和垂直方向坐标。
页面坐标位置
鼠标事件的event对象的pageX和pageY,是鼠标事件发生时,光标相对于页面的水平方向坐标和垂直方向坐标。pageX = clientX + 页面scrollLeft、pageY = clientY + 页面scrollTop
屏幕坐标位置
鼠标事件event对象的screenX和screenY,是鼠标事件发生时,光标相对于电脑屏幕的位置。
修改键
鼠标按下时,如果键盘上同时按下了某些键(称为“修改键”),鼠标事件的行为就可能需要修改。想要实现这样的效果,响应鼠标事件时,要判断event对象里保存的修改键的状态。DOM规定了4个属性来保存修改键状态:shiftKey、ctrlKey、altKey、metaKey(对应Windows系统的Windows键,和苹果系统的Cmd键),这4个属性都是布尔值,表示这些键有没有按下。
相关元素
相关元素是针对mouseover和mouseout事件的。
对mouseover事件来说,鼠标移入的元素就是目标元素,移出的元素(如果有的话)就是相关元素。对mouseout事件来说,鼠标移出的元素就是目标元素,移入的元素(如果有的话)就是相关元素。DOM标准规定event对象的relatedTarget属性就用来保存相关元素的信息(如果没有就为null)。
在IE8及更早版本,event对象没有relatedTarget属性,不过有fromElement和toElement属性。
鼠标按钮
鼠标事件发生时,event对象上有个button属性,表示触发事件的按钮是哪个(mousedown和mouseup事件就可能需要判断这个),button值为0表示主按钮(左键),为1表示中间按钮(滚轮),为2表示次鼠标按钮(右键)。
IE8及更早版本的event.button值比较一言难尽,就不抄了。然后作者介绍了如何编写方法把这点浏览器差异统一起来,用document.implementation.hasFeature("MouseEvents", "2.0")来判断是不是IE,如果为false说明是IE,对它进行统一化处理。
更多事件信息
DOM2级事件规范在event对象上规定了detail属性来提供更多信息。
鼠标滚轮事件
mousewheel事件可以在页面任何元素上触发。
mousewheel事件的event对象有一个属性wheelDelta,是个Number值,向前滚动滚轮时值为正,向后滚动滚轮时值为负。
浏览器差异:在Opera9.5之前这个wheelDalta的值正负号是颠倒的。Firefox不支持mousewheel而是支持DOMMouseScroll,并且它的滚轮事件event对象的wheelDalta值也是正负颠倒的。
触摸设备
看了下没啥要记的。。
无障碍性问题
为了使应用对视障用户更易使用,注意:用click来触发事件,不要用onmousedown因为屏幕阅读器不能触发mousedown;onmouseover也不能用屏幕阅读器触发,所以重要事件不要用onmouseover触发;dblclick,情况同上。
4.4 键盘与文本事件
有3个键盘事件:
keydown 按下任意键时触发,按住不放会重复触发
keypress 按下字符键和Esc键时触发,按住不放会重复触发
keyup 释放任意键时触发
以上3个事件所有元素都支持
还有一个文本事件textInput,为了更方便地截获用户的输入而设计的,在文本插入文本框之前会触发textInput。
当用户在文本框里输入,按下一个字符键的时候,依次触发以下事件:keydown、keypress、keyup(如果按住不放会重复触发keydown和keypress)。如果按下的是非字符键,触发事件如下:keydown、keyup
与鼠标事件一样,键盘事件也是有修改键的,在event对象的shiftKey、ctrlKey、altKey、metaKey中保存。
键码
keydown和keyup事件的event对象有个属性keyCode,表示按下/弹起的键是键盘上的哪个。
字符编码
keypress事件触发意味着按下的键会影响到屏幕中文本的显示,此时event对象的charCode属性值为按下的键的ASCII码。
浏览器差异:有些浏览器不支持charCode,会在keyCode存入按键的ASCII码。
DOM3级变化
DOM3级规定,不用charCode属性了,改用key和char属性。key值是个字符串,是按键的键名。char值在按键为字符键时为键名,按键为非字符键时为null。
实际上不同浏览器对这个特性的实现不同,Safari5和Chrome增加了个keyIdentifier属性,按下的是非字符键时值为键名,按下的是字符键时值为字符Unicode值。
DOM3还规定了个location属性,值为Number,表示按键的位置。实际上。。不同浏览器实现得也各有差异。
DOM3还规定了getModifierState方法,用于检测某个修改键是否有被按下,传入的参数是Shift/Control/AltGraph/Meta这样的字符串,返回的是布尔值。
蛮多余的。。不是已经有4个属性表示修改键按下的情况了。。。这个方法也没有被各浏览器统一实现
textInput事件
DOM3规定的textInput。特点:不是所有获得焦点的元素都可以触发textInput,只有可编辑区域能触发;只有按下输入字符的键才会触发textInput,退格键这种虽然会改变文本但不会触发;event对象包含一个data属性,表示按键时输入的字符内容,比如说按s时就是s,按shift+s时就是S;event对象包含inputMethod属性,是一个Number,表示文本变化的数据来源,1表示键盘输入/2表示文本粘贴/3表示文本拖放……/0表示浏览器不知道字符来源
设备中的键盘事件
其它设备如游戏机、屏幕等设备的按钮按下也可能触发键盘事件。
4.5 复合事件
DOM3中添加的一些事件,用于处理IME的输入序列。IME即Input Method Editor输入法编辑器,可以让用户输入键盘上没有的特殊字符。
不过作者说,这个特性支持得不怎么样,所以用途不大。
4.6 变动事件
DOM2级定义了一些DOM变动事件
删除节点
从DOM中删除节点时,会触发以下事件:
DOMNodeRemoved事件,目标是被删除的节点,event.relatedNode是目标节点的父节点。触发时,目标节点尚未从DOM删除。此事件可以冒泡,也就是可以在较高层次监听到。
DOMNodeRemovedFromDocument事件,在被删除的节点和其子节点上触发。这个事件不冒泡,不能在别的层次监听到。
DOMSubtreeModified事件,目标是被删节点的父节点。
插入节点
向DOM插入节点时,会触发以下事件:
DOMNodeInserted事件,目标是插入的节点,even.relatedNode是目标节点的父节点。触发时,目标节点已插入DOM。此事件可以冒泡,也就是可以在较高层次监听到。
DOMNodeInsertedIntoDocument事件,目标是插入的节点。这个事件不冒泡,不能在别的层次监听到。
4.7 HTML5事件
contextmenu
在上下文菜单要出现之前触发。
此事件可以冒泡,事件的目标元素为发生用户操作的元素。
在所有浏览器中都可以取消默认行为。
contextmenu属于鼠标事件,所以event对象有光标位置信息。
一般可以利用这个事件来展示自定义菜单,不使用默认的。
beforeunload
在页面卸载前触发。
可以在响应事件里return一串字符串(或者设置event.returnValue,视浏览器不同而定),作为提示语,给用户一些提示(比如说,离开后编辑的内容会丢失,是否确认离开。什么的)
DOMContentLoaded
window的load事件在页面中一切都加载完毕时触发。DOMContentLoaded是在DOM加载完成后触发,不理会图像、js、css等资源是否加载完毕。
目标元素是document
这个事件始终会在load事件之前触发。
有的浏览器不支持DOMContentLoaded,可以用setTimeout(callback,0)来代替,这句代码意思是“当前js处理完毕后运行回调”,在页面下载和构建期间,只有一个js处理过程,所以能在当前script标签内代码运行完后触发回调。为了保证效果,这句代码得作为页面里的第一个超时调用。
readystatechange
此事件的目的是提供与文档或元素加载状态有关的信息。
支持readystatechange的对象有一个readyState属性,值可能为:uninitialized未初始化,loading加载中,loaded加载数据完毕,interactive可交互DOM但尚未加载完毕,complete全部加载完毕
loaded和interactive这两者先后不一定,外部资源较少时可能loaded更早,外部资源较多时可能interactive更早,interactive甚至可能晚于complete。
document、script、link元素都支持readystatechange事件
支持readystatechange事件的浏览器有IE、Firefox4+、Opera
pageshow和pagehide
Firefox和Opera有一个“往返缓存”的功能,就是在浏览器前进、后退的时候并不删除当前页面数据,而是存在缓存中。因此被浏览器缓存的页面重新展示的时候,不会触发load事件。
为此,Firefox提供了pageshow和pagehide事件。
pageshow在页面显示时触发。不管页面是否来自缓存都会有,如果不是来自缓存的,会在load事件触发后触发。这个事件的目标是document但必须在window对象上注册监听。其event对象上有个persisted属性,如果页面在缓存中为true,否则为false。
pagehide事件在页面卸载时触发,在unload事件触发前触发。目标是document但必须在window对象上注册监听。其event对象上包含persisted属性,表示页面卸载后是否会被保存在浏览器缓存中。
小tip:指定了onunload事件处理程序的页面不会被缓存进浏览器。因为onunload监听器通常做一些与onload监听器里的操作相对应的操作,又因为存进缓存的页面会出现只有onunload没有onload的情况,所以又有onunload监听器又没有onload事件的页面可能会出错,考虑到这一点,浏览器不把有onunload的页面存进缓存。
hashchange
当URL的参数列表有变时触发(就是URL中#号后面字符串有变的情况下)。
这个事件要在window对象上注册监听。
其event对象包含两个属性,oldURL和newURL。
4.8 设备事件
移动设备的事件
orientationchange
Safari浏览器的事件,所有iOS设备都支持。event对象上没什么信息,window.orientation值会给出设备旋转情况,0正常/90主按钮在右侧/-90主按钮在左侧。
MozOrientation
Firefox3.6增加的,属于window事件。当设备的方向有变化时触发。event对象上有x、y、z属性,值为Number在1到-1之间,表示不同坐标轴上的方向。
只有带有加速计的设备才能支持这个事件。
这是一个实验性的API,之后可能会变。
deviceorientation
也是在加速计检测到设备方向变化时触发。但它给出的是设备当下的方向,不是设备方向在往什么方向变。
event对象上有5个属性:alpha范围0到360(在水平桌面上的旋转角度)、beta范围-180到180(围绕手机屏幕y轴转动的角度)、gamma范围-90到90(围绕手机屏幕x轴转动的角度)、absolute表示设备是否返回一个绝对值、compassCalibrated表示设备的指南针是否校准过
devicemotion
event对象包含:acceleration包含xyz三个属性表示各方向上的加速度(不包括重力),accelerationIncludingGravity包含xyz三个属性表示各方向上的加速度(包括重力),interval修改它的值告诉浏览器下次触发devicemotion的时间间隔,rotationRate包含alpha、beta、gamma三个属性
4.9 触摸与手势事件
移动设备的兴起促使W3C开始指定Touch Events规范。
触摸事件
touchstart触屏时触发
touchmove手指在屏幕上滑动时触发,在监听器中preventDefault可以阻止滚动
touchend手指离开屏幕时触发
touchcancel系统停止跟踪触摸时触发,但这个事件触发的条件文档里没有明确规定。
以上这些事件会冒泡,它们都包含鼠标事件里常见的属性(定位的那些属性,是否同时有按下修改键那些),文档上所有元素都可以触发这些事件
此外,以上事件的event还包含以下属性:touches当前正在跟踪的触摸对象数组、targetTouches针对目标元素的触摸对象数组、changeTouches发生改变的触摸对象数组(都是数组,因为同时可能有不止一根手指在滑屏)
触屏时以下事件依次发生:touchstart、mouseover、mousemove(一次)、mousedown、mouseup、click、touchend
手势事件
Safari引入的手势事件:
gesturestart当一个手指正在触屏时,另一个手指又开始触屏
gesturechange任意一个触屏手指改变位置
gestureend任意手指结束触屏
以上事件的event除了包含鼠标事件里的常见属性,还有rotation和scale。rotation表示手势表示的旋转角度,scale表示手势表示的缩放倍数。
5.内存和性能
在C#中,加个onclick之类的监听器是很随意的事情。但在JavaScript中,注册太多事件监听器会影响性能,原因一:监听器是对象,会占用内存,原因二:注册时需要访问DOM,如果页面加载完需要注册很多监听器就会很卡。
5.1 事件委托
利用事件冒泡,把同类的监听都委托给一个总监听,比如click事件,因为它会冒泡,所以可以给document注册一个click事件的总监听,而不需要再各层次元素上分开注册。
总监听内部对目标元素做区分判断。
5.2 移除事件处理程序
removeChild、replaceChild方法移除元素时,尤其是用innerHTML替换元素内容时,容易发生原先注册的监听器没有被销毁的情况,注意手动移除事件处理程序再移除元素。
小tip:由于删除元素会阻止事件冒泡,所以如果响应点击时删了目标元素,高层元素会监听不到事件冒泡。不留心这点容易制造bug。
小tip:页面卸载前也要注意释放监听器,否则它们会滞留在浏览器内存中。
6.模拟事件
事件除了通过用户操作和浏览器的一些功能来触发,js自己也能主动触发一些事件。
6.1 DOM中的事件模拟
要模拟事件,可用document.createEvent方法,参数为要创建的事件类型的字符串。
创建了Event对象之后,对其进行初始化,使其具备必要的信息,然后调用DOM元素的dispatchEvent方法。触发后,这个模拟事件就跟“官方事件”行为一样了。
模拟鼠标事件
document.createEvent('MouseEvent'),然后调用返回的事件对象的initMouseEvent方法,传入一堆参数,我就不抄了。
模拟键盘事件
DOM2中没有定义模拟键盘事件,所以这节讲的是DOM3级里的定义,以及Firefox和其它浏览器的自己的实现
模拟其它事件
document.createEvent("MutationEvents")可以创建一个变动事件对象。“其它事件”包括节点删改事件,焦点事件等。
自定义DOM事件
document.createEvent('CustomEvent')可以创建自定义事件,与以上“官方事件类型”稍有不同的是,initCustomEvent要传入这个自定义事件是否冒泡、是否可以取消。
6.2 IE中的事件模拟
IE的模拟事件与DOM有所不同,它是用document.createEventObject方法。然后给返回的事件对象加上必要的信息。然后在目标元素上调用fireEvent方法。