事件类型(event type)是一个用来讲明发生什么类型事件的字符串。javascript
因为事件类型只是一个字符串,所以实际上有时会称之为事件名字。咱们用这个名字来标识所谈论的特定类型的事件。html
事件目标(event target)是发生的事件或与之相关的对象。当讲事件时,咱们必须同时指明类型和目标。例如,window上的load事件或button上的click事件java
在客户端的javascript应用程序中,window、document和element对象是最多见的事件目标。但某些事件是有其余类型的对象触发。例如,由XMLHttpRequest对象触发的readystatechange事件jquery
事件处理程序(event handler)或事件监听程序(event listener)是处理和响应的函数。应用程序指明事件类型和事件目标,在web浏览器中注册它们的事件处理程序函数,当在特定的目标上发生特定类型的事件时,浏览器会调用对应的处理程序。当对象上注册的事件处理程序被调用时,咱们有时会说浏览器触发)(fire trigger)和派发了事件。web
event object 事件对象是与特定事件相关且包含有关该事件详细信息的对象。事件对象做为参数传递给事件处理程序函数(不包括ie8及以前版本,在这些浏览器中有时仅能经过全局变量event才能获得),全部的事件对象都有用来指定事件类型的type属性和指定事件目标的target属性。)(在IE8及以前版本中用srcElement而非target)。每一个事件类型都为其相关事件对象定义一组属性chrome
事件传播(event propagation)是浏览器决定哪一个对象触发其事件处理程序的过程。对于单个对象的特定事件(好比window对象的load事件),必须是不能传播的。当文档元素上发生某个类型的事件时,然而。它们会在文档树上向上传播或冒泡,事件处理程序能经过调用方法或设置事件对象属性来阻止事件传播,这样它就能中止冒泡且将没法在容器上触发处理程序。浏览器
事件传播的另一种形式称为事件捕获(event capturing),在容器元素上注册的特定处理程序网络
有机会在事件传播到真实目标以前拦截(捕获)它。IE8及以前版本不支持事件捕获,因此不经常使用它,可是,当处理鼠标拖放事件时,捕获或夺取鼠标事件的能力是必须的dom
一些事件有与之相关的默认操做,当超连接上发生click事件时,浏览器的默认操做是按照连接加载页面,事件处理程序能够经过返回一个适当的值,调用事件对象的某个方法或者设置事件对象的某个属性来阻止默认操做的发生。这有时称为取消事件。异步
一、表单事件,当提交表单和重置表单时,form元素会分别发生submit和reset事件,当用户和类按钮表单元素(包括单选按钮和复选按钮)交互时,它们会发生click事件。当用户经过输入文字、选择选项或选择复选框来改变相应表单元素的状态时,这些一般维护某种状态的表单元素会触发change事件。对于文本输入域,只有用户和表单元素完成交互并经过tab键或者单击的方式移动焦点到其余元素上时才会触发change事件 。响应经过键盘改变焦点的表单元素在获得和失去焦点时会分别触发focus和blur事件
经过事件处理程序能取消submit和reset事件的默认操做,某些click事件也是如此。focus和blur事件不会冒泡,但其余全部表单事件均可以。ie定义了focusin和focusout事件能够冒泡,它们能够永远替代focus和blur事件。
不管用户什么时候输入文字(经过键盘或剪切和粘贴)到textarea和其余文本输入表单元素,除ie外的浏览器都会触发input事件。不像change事件,每次文字插入都会触发input事件,遗憾的是,input事件的事件对象没有指定输入文字的内容(textinput事件将会成为这个事件的有用替代方案。)
window事件
是指事件的发生与浏览器自己而非窗口中显示的任何特定文档内推相关,可是,这些事件中有一些会和文档元素上发生的事件同名
load事件,当文档和其全部外部资源(好比图片)彻底加载并显示给用户时就会触发它。DOMContentLoaded和readystatechange是load事件的替代方案,当文档和其元素为操做准备就绪,但外部资源彻底加载完毕以前,浏览器就会尽早触发它们。
unload事件 和load相对,当用户离开当前文档时转向其余文档时会触发它,unload事件处理程序能够用于保存用户的状态,但它不可能用于取消用户转向其余地方。beforeunload事件和unload相似,但它能提供询问用户是否肯定离开当前页面的机会。若是beforeunload的处理程序返回字符串,那么在新页面加载以前,字符串会出如今展现给用户确认的对话框上,这样用户将有机会取消其跳转而留在当前页面上。
window对象的onerror属性有点像事件处理程序,当javascript出错时会触发他。可是,它不是真正的事件处理程序,由于它能用不一样的参数来调用。
想img元素这样的单个文档元素也能为load和error事件注册处理程序。当外部资源(例如图片)彻底加载或发生阻止加载的错误时就会触发它们。某些浏览器也支持也支持abort事件,当图片(或其余网络资源)由于用户中止加载进程而致使失败就会触发它。
表单元素的focus和blur事件也能用作window事件,当浏览器窗口从操做系统中获得或者失去键盘焦点时会触发它们。
当用户调整浏览器窗口大小或滚动它时会触发resize和scroll事件,scoll事件也能在任何能够滚动的文档元素上触发,好比那些设置CSS的overflow属性的元素。传递给resize和scroll事件处理程序的事件对象是一个很是普通的Event对象,它没有指定调整大小或发生滚动的详细信息属性。
鼠标事件
当用户在文档上移动或单击鼠标时都会发生鼠标事件。这些事件在鼠标指针所对应的最深嵌套元素上触发,但它们会冒泡知道文档最顶层。传递给鼠标事件处理的事件对象有属性集,它们描述了当事件发生时鼠标的位置和按键状态,也指明了当时是都有任何辅助建按下。clientX和clientY属性指定了鼠标在窗口坐标中的位置,button和which属性指定了按下的鼠标键是哪一个。当键盘辅助键按下时,对应的属性altkey、ctrlKey、metaKey和shiftKey会设置为true,对于click事件,detail属性指定了其实单击、双击仍是三击。
当用户按下或释放鼠标按键时,会触发mousedown和mouseup事件。经过注册mousedown和mouseomove事件处理程序,能够探测和响应鼠标的拖动。合理的这样作可以捕获鼠标事件,甚至当鼠标从开始元素移出时咱们都能持续的接受到mousemove事件。
在mousedown和mouseup事件队列以后,浏览器也会触发click事件。若是用户在至关短的时间内连续两次单击鼠标按键,跟在第二个click事件以后是dbclick事件。当单击鼠标右键时,浏览器一般会显示上下文菜单(context menu)。在显示菜单以前,它们一般会触发contextmenu事件,而取消这个事件就能够阻止菜单的显示。这个事件也是得到鼠标右击通知的简单方法。
当用户移动鼠标指针从而使它悬停到新元素上时,浏览器就会在该元素上触发mouseover事件。当鼠标移动指针从而使他再也不悬停在某个元素上时,浏览器就会在该元素上触发mouseout事件。对于这些事件,事件对象将有related属性指明这个过程涉及的其余元素。mouseover和mouseout事件和这里介绍的全部鼠标事件同样会冒泡。正由于如此,IE提供了这些事件的不冒泡版本mouseenter和mouseleave,jquery模拟非IE的浏览器中这些事件的支持
当用户滚动鼠标滚轮时,浏览器触发mousewheel事件(或在firefox中是DOMMouseScroll事件)。传递的事件对象属性指定滚轮转动的大小和方向。3级DOM事件规范正在标准化一个更通用的多维wheel事件
键盘事件
当键盘聚焦到web浏览器时,用户每次按下或释放键盘上的按键时都会产生事件。不管任何文档元素得到键盘焦点都会触发键盘事件,而且他们会冒泡到Document和window对象。若是没哟元素得到焦点,能够直接在文档上触发事件。传递给键盘事件处理程序的事件对象有keyCode字段。它指定按下或释放的键是哪一个,除了keyCode,键盘事件对象也有altKey,ctrlKey、metaKey和shiftKey,描述键盘辅助建的状态。
keydown和keyup事件是低级键盘事件,不管什么时候按下或释放按键(甚至是辅助建)都会触发它们。当keydown事件产生可打印字符时,在keydown和keyup之间会触发另一个keypress事件。当按下键重复产生字符时,在keyup事件以前可能产生keypress。keypress是较高级的文本事件,其事件对象指定产生的字符而非按下的键。全部浏览器支持keydown、keyup和keypress事件。
dom事件
3级DOM事件规范标准了不冒泡的focusin和focusout事件来取代冒泡的focus和blur事件,标准化了冒泡的mouseenter和mouseleave事件来取代不冒泡的mouseover和mouseout事件
3级dom事件规范中新增内容有经过wheel事件对二维鼠标滚轮提供标准支持,经过textinput事件和传递新KeyboardEvent对象做为参数给keydown、keyup和keypress的处理程序来给文本输入事件提供更好的支持。
wheel事件的处理程序接收到的事件对象除了全部普通鼠标鼠标事件属性,还有deltaX、deltaY、deltaZ属性来报告三个不一样的鼠标滚轴。大多数鼠标滚轮上是一维或者两维,并不使用deltaZ。
3级DOM事件规范了keypress事件,但不同意使用它而使用称为textinput的新事件。传递给textinput事件处理程序的事件对象再也不有难以使用的数字keyCode属性,而有指定输入文本字符串的data属性。textinput事件不是键盘特定事件,不管经过键盘、剪切和粘贴、拖放等方式,每当发生文本输入时就会触发它,规范定义了事件对象的inputMethod属性和一直表明各类文本输入种类的常量(键盘、粘贴、拖放、手写、语音识别),safari和chrome使用混合大小的textInput来支持这个事件版本,其事件对象有data属但没有inputMethod属性。
注册事件处理程序
有两种基本方式
第一种,给事件目标对象或文档元素设置属性。第二种方式,是将事件处理程序传递给对象或元素的一个方法,每种技术都有两个版本。能够在javascript代码中设置事件处理程序为对象属性,或对于文档元素,能够在html中直接设置相应属性。对于经过方法调用的处理程序注册,有一个标准方法,命名为addEventListener,除IE8及之前版本以外,全部浏览器都支持这个方式,而ie9以前的IE版本支持的是一个叫attachEvent的不一样方法。
注册事件处理程序最简单的方式就是经过设置事件目标的属性为所需事件处理程序函数。事件处理程序属性的名字由“on”后面跟着事件名组成。全部都是大小写。
设置HTML标签属性为事件处理程序
若是这样作,属性值应该是javascript代码字符串。这段代码应该是事件处理程序函数的主体,而非完整的函数声明。也就是说,HTML事件处理程序代码不该该用大括号包围且使用function关键字做为前缀。
<button onclick="alert('thank you');">点击这里《/button》
若是HTML事件处理程序属性包含多条javascript语句,要记住必须使用分号分隔这些语句或断开属性值使其跨多行。
某些事件类型一般直接在浏览器而非任何特定文档元素上触发。在javascipt中,这些事件处理程序在window对象上注册。
在html中,会把他们放在body标签上,但浏览器会在window对象上注册它们
在除IE及以前版本外的全部浏览器都支持的标准事件模型,任何能成为事件目标的对象-包括Window对象、Document对象和全部文档元素--都定义了一个名叫addEventListener的方法。使用相同的参数在同一个对象上屡次调用addEventListener是没用的,处理程序仍然只注册一次,同时重复调用也不会改变调用处理程序的顺序。
相对addEventListener的是removeEventLister
document.removeEventListener("mouseup",handleMouseUp,true);
attachEvent和detachEvent方法的工做原理与addEventListenner和removeEventListent相似,但有以下例外:
一、由于IE事件模型不支持事件捕获,因此attachEvent和detachEvent要求只有两个参数:事件类型和处理程序函数。
二、IE的第一参数使用了带on前缀的事件处理程序属性名,而非没有前缀的事件类型
三、attachEvent容许相同的事件处理程序函数注册。当特定的事件类型发生时,注册函数的调用次数和注册次数同样
事件处理程序的参数
一般调用事件处理程序时把事件对象做为他们的一个参数(有一个例外)。事件对象的属性提供了有关事件的详细信息,例如,type属性指定了发生的类型。
在IE8及之前版本中,经过设置属性注册处理程序,当调用它们时并未传递事件对象,取而代之,须要经过全局对象window.event来得到事件对象
function handler(event){
var event=event||window.event;
}
向使用attachEvent注册的事件处理程序传递事件对象,但它们也能使用window.event,当经过设置HTML属性注册事件处理程序时,浏览器会把javascript编码转换到一个函数中。非IE浏览器使用event参数来构造函数,而IE在构造函数时没有有要求参数。若是在这样的函数中使用event标识符,那么引用的正是Window.event.在这两种状况下,HTML事件处理程序都能做为event引用事件对象。
e.onclick=function(){};
事件处理程序在事件目标上定义,因此它们做为这个对象的方法来调用。这就是说,在事件处理程序内,this关键字指的是事件目标。当使用addEventListener注册时,调用的处理程序使用事件目标做为它们的this值。可是,对于attachEvent来说这是不对的:使用attachEvent注册的处理程序做为函数调用,它们的this值是全局对象(window)。能够用以下代码来解决这个问题:
function addEvent(target,type,handler){ if(target.addEventListener){ target.addEventListener(type,handler,fasle); } else{ target.attachEvent("on"+type,function(event){ return handler.call(target,event); //把处理程序做为事件目标的方法调用,传递事件对象 }) } }
注意使用这个方法注册的事件处理程序不能删除,由于传递给attchEvent的包装函数没有保留下来传递给detachEvent。
事件处理程序的返回值
经过设置对象属性或HTML属性注册事件处理程序的返回值有时是很是有意义的。一般状况下,返回值false就是告诉浏览器不要执行这个事件相关的默认操做。例如,表单提交按钮的onclick事件处理程序能返回false阻止浏览器提交表单.相似的,若是用户输入不合适的字符,输入域上onkeypress事件处理程序能经过返回false来过滤输入
winodw对象的onbeforeload事件处理程序的返回值也很是有意义的,当浏览器将好跳转到新页面时触发这个事件。若是事件处理程序返回一个字符串,那么它将出如今询问用户时候想离开当前页面的标准对话框中。
理解事件处理程序的返回值只对经过属性注册的处理程序才有意义这很是重要。接下来咱们将看到使用addEventListener或attchEvent注册事件处理程序转而必须调用preventDefault方法或设置事件对象returnValue属性。
调用顺序
文档元素或其余对象能够为指定事件类型注册多个事件处理程序。当适当的事件发生时,浏览器必须按照以下规则调用全部的事件处理程序:
经过设置对象属性或HTML属性注册的处理程序一直优先调用。
使用addEventListener注册的处理程序按照它们的注册属性调用。
使用attachEvent注册的处理程序可能按照任何顺序调用,全部代码不该该依赖于调用顺序。
在调用在目标元素上注册的事件处理函数后,大部分事件会冒泡到Dom树根。调用目标的父元素的事件处理程序,而后调用在目标的祖父元素上注册的事件处理程序。这会一直到Document对象,最后到达window对象。发生在文档元素上的大部分事件都会冒泡,值得注意的例外是focus、blur和scroll事件,文档元素上的load事件会冒泡,但它会在Document对象上中止冒泡而不会传播到Window对象。只有当整个文档都加载完毕时才会触发window对象的load事件。
事件取消
在支持addEventListener的浏览器中,也能经过调用事件对象的preventDefault方法取消事件的默认操做。不过,在IE9以前的IE中,能够经过设置事件对象的returnValue属性为false来达到false来达到一样的效果。
取消事件相关的默认操做只是事件取消的一种,咱们也能取消事件传播。在支持addEventListener的浏览器中,能够调用事件对象的一个stopPropagation方法已阻止事件的继续传播。若是在同一对象上定义了其余处理程序。剩下的处理程序将依旧被调用,但调用stopPropagation以后任何其余对象上的事件处理程序将不会被调用。stopPropatation方法能够在事件传播期间的任什么时候间调用,它能工做在捕获阶段、事件目标自己中和冒泡阶段。ie9以前的IE不支持stopPropagation方法。相反,ie事件对象有一个cancelBubble属性,设置这个属性为true能阻止事件进一步传播(ie8及以前版本不支持事件传播的捕获阶段,因此冒泡是惟一待取消的事件传播)
事件捕获提供了事件没有送达目标以前查看它们的机会。事件捕获能用于程序调试或用于后面介绍的事件取消技术,过滤掉事件从而是目标处理程序不会被调用。事件捕获经常使用月处理鼠标拖放,由于要处理拖放事件的位置不能是这个元素内部的子元素
文档加载事件
Window的load事件直到文档和全部图片加载完毕才发生。当文档加载解析完毕且全部延迟脚本都执行完毕时会触发DOMContentLoaded事件,此时图片和异步脚本可能依旧在加载,可是文档已经为操做准备就绪了,被包括IE9在内的全部其余浏览器厂商采用
document.readyState属性随着文档加载过程而变,在IE中,每次状态变化都伴随着document对象上的readystatechange事件,当ie接收到completely状态时使用这个事件来判断是可行的。
鼠标事件
除了mouseenter和mouseleave外的全部鼠标事件都能冒泡,连接和提交按钮上的click事件都有默认操做且可以阻止。能够取消上下文菜单事件来阻止显示上下文菜单。
mouseover 当鼠标进入元素时触发,relatedtarget(在ie中是fromElement)指的是鼠标来自的元素
mouseout 当鼠标离开元素时触发,relatedTarget(在ie中是toElement)指的是鼠标要去往的元素
传递给鼠标事件处理程序的事件对象有clientX和clientY属性,它们指定了鼠标指针相对于包含窗口的坐标,加入窗口的滚动偏移量就能够把鼠标位置转换文档坐标。
altkey,ctrlkey,metakey和shiftkey属性指定了当事件发生时是否有各类键盘辅助键按下,例如,这让你可以区分普通单击和按着shift键的单击
鼠标滚轮事件
全部的现代浏览器都支持鼠标滚轮,并在用户滚动滚轮时触发事件,浏览器一般使用鼠标滚轮滚动或缩放文档,但能够经过取消mousewheel事件来阻止这些默认操做。除了firefox以外的全部浏览器都支持mousewheel事件,但firefox使用DOMMouseScroll