js013-事件
本章内容
理解事件流
使用时间处理程序
不同的事件类型
JS与HTML之间的交互是通过实践实现的。时间就还文档或浏览器窗口发生的一些特定的交互 瞬间。可以使用侦听器来预定事件,以便时间发生时执行乡音的代码。
13.1 事件流
事件流描述的是从页面中接收事件的顺序。IE的事件流是冒泡流,Netscape Communicator的事件流是捕获流。
13.1.1事件冒泡
IE的事件流叫做时间冒泡:时间开始由具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
如下例子:
<!DOCTYPE html> <html> <head> <title>sample page</title> </head> <body> <div id="lal-Alice">a software enginer</div> </body> </html> |
如果你单击了页面中的<div>元素,那么这个click事件会如下顺序传播:
<div>
<body>
<html>
document
13.1.2事件捕获
思想:不太具体的节点应该更早的接收到事件,最具体的节点应该最后接收到时见。
用意:在事件到达预定目标之前捕获它。
如上例子,如果你单击了页面中的<div>元素,那么这个click事件会如下顺序传播:
document
<html>
<body>
<div>
13.1.3 DOM事件流
“DOM2级事件”规定的事件流包括三个阶段:时间捕获阶段,处于目标阶段和时间冒泡阶段。
如上例子,如果你单击了页面中的<div>元素,那么这个click事件会如下顺序传播:
document
<html>
<body>
(上为捕获阶段,下为冒泡阶段。)
<div>
<body>
<html>
document
13.2 事件处理程序
事件就是用户或者浏览器自身之星的某种动作,如click,load ,mouseover,都是时间的名字,而相应某个事件的函数就叫做时间处理程序(或者事件侦听器)。
事件处理程序的名字以“on”开头,所以click事件的处理程序就是onclick。为事件指定处理程序的方式有好几种。
13.22.1 HTML事件处理程序
某个元素支持的美中事件,都可以使用一个与之对应的时间处理程序同名的HTML特性来指定。这个特性的值,应该是能够执行JS代码的。例如:要在按钮被单击时执行一些JS,可以像下面那样编写代码:
<input type="button" value="cklick me" onclick="alert(‘clicked‘)" /> |
如果要使用双引号,,则如下编写代码
<input type="button" value="cklick me" onclick="alert("clicked")" /> |
在HTML中定义的时间处理程序可以包含要执行的具体动作,也可以调动在页面其他地方定义的脚本。如下所示:
<script type="text/javascript"> function showmessage(){ alert("Hello word!"); } </script> <input type="button" value="click me" onclick="showmessage()" /> |
这个例子中,单击按钮就会调用showmessage()函数
如果在函数定义之前淡季了按钮会发生错误,但是可以吧时间吃力程序封装在一个try-catch块中。如
<input type="button" value="click me" onclick="try{showmessage();}catch(ex)" /> |
13.2.2 DOM0级事件处理程序
通过JS制定时间处理程序的方式是将一个函数赋值给一个事件处理程序属性。这种方法简单,并且具有夸浏览器的优势,要使用JS制定时间处理程序,收下必须取得一个要操作的对象引用。
每个元素都有自己的事件处理程序属性。一般小写将这种属性的值设置为一个函数,就可以指定事件处理程序。
如下
var btn = document.getElementBId("mybutton"); btn.onclick = function(){ alert("clicked"); }; |
13.2.3 DOM2级事件处理程序
DOM2级事件 定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener() removeEventListener().所有DOM节点都好汉这两个方法。他们都接收3个参数:要处理的事件名,作为处理程序的函数和一个布尔值,该布尔值如果是true表示在捕获阶段,false表示在冒泡阶段
通过addEventListener()添加的事件处理程序只能通过removeEventListener().来移除,移除是传入的参数与添加是使用的参数一样。。所以addEventListener()添加的匿名函数将无法移除。
13.2.4 IE事件处理程序
IE实现了DOM中类似的两个方法attachEvent() detachEvent(). 接收两个参数:事件处理程序名称和事件处理程序函数。因为I8之前版本只支持事件冒泡所以通过attachEvent()添加的事件处理程序会被添加到冒泡阶段。
用attachEvent()添加一个事件处理程序
var btn = document.getElementBId("mybutton"); btn.attachEvent("onclick", function(){ alert("clicked"); }); |
在IE中使用attachEvent()与使用DOM0级方法的主要区别是事件处理程序的作用域;DOM0级方法:在所属元素作用域内运行;attachEvent():在全局作用域中运行。
13.2.5跨浏览器的事件处理程序
13.3 事件对象
所有浏览器都支持event对象,但支持方式不同。
13.3.1 DOM中的事件对象
兼容DOM的浏览器会将一个event对象传入到事件处理程序中。无论指定事件处理程序时使用什么方法,都会传入事件对象。
所有的事件都会有下列成员:(未完成)
属性/方法 |
类型 |
读/写 |
说明 |
在事件处理程序内部,对象this始终等于currentTarget的值。而target则只包含事件的实际目标
13.3.2 IE中的事件对象
要访问IE中的事件对象有几种不同过得方式,取决于指定事件处理程序的方法。IE的实践对象也包含于创建它的事件相关的属性和方法,这些属性和方法,也会因为事件类型的不同而不同事件都会包含鞋类所有的属性和方法:
属性/方法 |
类型 |
读/写 |
说明 |
cancelBubble |
Boolean |
读/写 |
默认为false值,将其设置为true就可以取消事件冒泡(与ODM中的stopPropagation()方法作用相同) |
returnValue |
Boolean |
读/写 |
默认为true,设置为false就可取消事件的默认行为(与ODM中的preventDefault()方法作用相同) |
srcElement |
Element |
只读 |
事件的目标(与ODM中的target属性作用相同) |
type |
String |
只读 |
被触发的事件类型 |
13.3.3跨浏览器的事件对象
虽然DOM和IE中的事件对象不同,但是基于它们之间的相似性依旧可以拿出跨浏览器的方案来。以下四种方法:
1、添加如下方法求同存异:
var EventUtil = { addHandler: function(element, type, handler){ //code }, getEvent: function(event){ return event ? event :window.event; }, getTarget: function(event){ return event.targe || event.srcElement; }, preventDefault: function(event){ if (event.preventDefault) { event.preventDefault(); }else{ event.returnValue = fasle; } }, removeHandler: function(element, type,handler){ //code }, stopPropagation: function(event){ if (event.stopPropagation) { event.stopPropagation(); }else{ event.cancelBubble = true; } } }; |
2、getTarget()方法
这个方法返回事件的目标
3、preventDefault()方法
用于取消事件的默认行为
4、stopPropagation()方法
首先尝试使用DOM方法阻止事件流,否则就是用cancelBubble属性。
13.4 事件类型
DOM3级事件规定了一下几类事件:
1、UI事件,当用户与页面上的元素交互触发;
2、焦点事件,当元素获得或失去焦点时触发;
3、鼠标事件,当用户通过鼠标在页面上执行操作是触发;
4、滚轮事件,当使用鼠标滚轮是触发;
5、文本事件,在文档中输入文本时触发;
6、键盘事件,用户通过键盘在页面上执行操作时触发;
7、合成事件,当为IME(输入法编辑器)输入字符时触发;
8、变动事件,当底层DOM结构发生变化时触发
9、变动名称事件,当uansu或属性名称变动时触发。(不做介绍)
13.4.1 UI事件
有UI事件如下:
事件 |
说明 |
DOMActivite |
元素已被用户操作过 |
load |
页面完全加载后再window上触发 |
unload |
页面完全卸载后再window上触发 |
abort |
用户停止下载过程,如果嵌入的内容没有加载完,在<object>元素上触发 |
error |
发生JS错误时在window上触发 |
select |
用户选择文本框中的一个或多个字符时触发 |
resize |
窗口或框架大小发生变化时在window上触发 |
scroll |
用户滚动带滚动条的元素中的内容是,在该元素上触发 |
1、load事件 最常用的JS事件
2、unload事件 与load事件相对应
3、resize事件
4、scroll事件 虽是在window上触发,但是表现则是在页面中乡音元素的变化。
13.4.2 焦点事件
当元素获得或失去焦点时触发。利用这事件与document.hasFocus()方法及document.activeElement属性配合,可以知晓用户在页面上的行踪。
焦点事件有一下六个:
blur |
元素失去焦点时触发,该事件不会冒泡,所有浏览器都支持它 |
DOMFocusIn |
元素获得焦点时触发,DOM3级废弃它了,选择使用focusin |
DOMFocusOut |
元素失去焦点时触发,DOM3级废弃它了,选择使用focusout |
focus |
元素获得焦点时触发,该事件不会冒泡,所有浏览器都支持它 |
focusin |
元素获得焦点时触发,和focus等价 |
focusout |
元素失去焦点时触发 |
当一个焦点从页面中的一个元素移动到另一个元素,会发生下列事件:
1、focusout在失去焦点的元素上触发
2、focusin在获得焦点的元素上触发
3、blur在失去焦点的元素上触发
4、DOMFocusOut在失去焦点的元素上触发
5、focus在获得焦点的元素上触发
6、DOMFocusIn在获得焦点的元素上触发
13.4.3鼠标与滚轮事件
DOM3级定义了以下9个鼠标事件
事件 |
触发场景 |
click |
单击鼠标按钮或者按回车键时,可以通过键盘触发这个事件 |
dblclick |
双加鼠标按钮,不能通过键盘触发这个事件 |
mousedown |
按下任何鼠标按钮时,不能通过键盘触发这个事件 |
mouseenter |
鼠标光标从元素外部首次移动到元素范围内时 |
mouseleave |
在位于元素上的鼠标光标移动到元素范围之外时 |
mousemove |
鼠标指针在元素内部移动时重复触发,不能通过键盘触发这个事件 |
mouseout |
在鼠标指针位于一个元素商法,然后用户将其移动到另一个元素时,不能通过键盘触发这个事件 |
mouseover |
鼠标指针在一个元素外部,将其首次移入另个元素边界之时。不能通过键盘触发这个事件 |
mouseup |
用户释放鼠标时,不能通过键盘触发这个事件 |
页面上的所有元素都支持鼠标事件,除了mouseenter和mouseleave,所有的鼠标事件都会冒泡,也可以被取消,如果mouseup和mousedown其中一个被取消,则click就不会触发。这四个事件触发的顺序如下:
mousedown
mouseup
click
mousedown
mouseup
click
dblclick
1~10 p370~p378 还没认真看
13.4.4 键盘与文本事件
3个键盘事件
keydown:按下键盘上任意键时触发,如果按住不放,会重复触发。
keypress:按下键盘上的字符键时触发,如果按住不放,会重复触发。
keyup:释放键盘上的键时触发
所有元素都支持以上3个事件。
细节还没认真看
13.4.5复合事件
3中复合事件:
compositionstart:在IME的文本复合系统打开时触发,表示要开始输入了;
compositionupdate:在向输入字段中插入新的字符时触发
compositionend:在IME的文本复合系统关闭时触发,表示返回正常键盘输入状态;
13.4.6变动事件
如下几个变动事件
DOMSubtreeModfied:在DOM结构中发生任何变化时,该事件在其他任何事件触发后都会触发;
DOMNodeInserted:在一个节点作为子节点被插入到另一个节点中时触发
DOMNodeRemove:在节点从其父节点中被移除时触发
DOMNodeInsertedtoDocument:在一个节点被直接插入文档或通过字数简介插入文档之后触发,
DOMNodeRemoveFormDocument:在一个节点被直接从文档删除或通过字数简介从文档删除之后触发,
DOMCharacterDataModified:文本节点的值发生变化时
细节还没认真看
13.4.7
HTML5事件
6个事件。笔记未写
13.4.8 设备事件
4个事件,笔记未写
13.4.9 触摸与手势事件
2个事件笔记未写
13.5 内存和性能
13.5.1事件委托
对“事件处理程序过多”问题的解决方案就是事件委托,利用了事件冒泡,指定一个事件处理程序,就可以管理某一类型的所有事件
最适合采用时间委托技术的事件,包括:click、mousedown、mouseup、keydown、keypress事件
13.5.2移除事件处理程序
1、从文档中移除带有时间吹程序的元素时可能会造成内存中存留有些过时不用的“空事件处理程序“也是造成web应用内存与性能问题的主要原因。removeChild()和replaceChild()方法或者innerHTML替换页面中的某一部分的时候。
2、卸载页面时也会导致“空事件处理程序“。
解决方法:在页面卸载之前,先通过onunload事件处理程序移除所有事件处理程序。
13.6 模拟事件
13.6.1
DOM中的事件模拟
步骤:
1、在document对象上使用createEvent()方法创建事件对象,接收一个参数:表示要创建的事件类型的字符串。可以时一下几个字符串之一:
UIEvents:一般化的UI事件。鼠标事件和键盘事件都是继承与UI事件
MouseEvents:一般化的鼠标事件,
MutationEvents:一般化的DOM变动事件
HTMLEvents:一般化的HTML事件
2、触发事件:使用dispatchEvent()方法,传入一个参数:表示要触发事件的event对象。
一、模拟鼠标事件
在createEvent()传入MouseEvents。返回一个名为initMouseEvent()方法,该方法接收15个参数。参数如下
再补充笔记
二、模拟键盘事件
在createEvent()传入KeyboardEvents返回一个名为initKeyEvent()方法,该方法接收9个参数。参数如下
再补充笔记
13.6.2
IE中的事件模拟
思路与DOM中的模拟事件相似,先创建事件对象,然后为其制定乡音的信息,然后再使用该对象来触发事件。