宝哥软件园

javascript中事件处理的详细说明

编辑:宝哥软件园 来源:互联网 时间:2021-09-27

一、事件传播机制。

客户端JavaScript程序(只是浏览器)采用异步事件驱动编程模型。当文档、浏览器、元素或相关对象发生有趣的事情时,网络浏览器会生成事件。如果JavaScript应用程序关注特定类型的事件,它可以注册一个或多个函数,以便在此类事件发生时调用。当然,这种风格并不是Web编程独有的,所有使用图形用户界面的应用程序都采用这种风格。

既然我们想详细解释事件处理,让我们从几个基本概念开始:

(1)事件类型:是用来说明发生什么类型事件的字符串。例如,“mousemove”表示用户移动鼠标,“keydown”表示按下键盘上的某个键。事件类型只是一个字符串,有时称为事件名称。

事件目标:是事件发生或与之相关的对象。窗口、文档和元素对象是最常见的事件目标。当然,AJAX中的XMLHttpRequest对象也是一个事件目标;

事件处理程序:处理或响应事件的函数,也称为事件监听器。应用程序通过指示事件类型和事件目标在网络浏览器中注册它们的事件处理程序。

事件对象:是与特定事件相关的对象,包含事件的详细信息。事件作为参数传递给事件处理程序(然而,在IE8和以前的版本中,全局变量事件是事件对象)。事件有一个用于指定事件类型的类型属性和一个用于指定事件目标的目标属性(但是在IE8及其早期版本中,使用了srcElement而不是target)。当然,不同类型的事件也为它们相关的事件对象定义了一些其他独特的属性。例如,鼠标事件的相关对象将包含鼠标指针的坐标,而键盘事件的相关对象将包含按下的键和辅助键的细节。

上面已经描述了四个基本概念。那么问题——来了。如果在网页上用鼠标点击元素A的子元素B,应该先执行子元素B注册的事件处理程序,还是先执行元素A注册的事件处理程序(假设元素A及其子元素B都注册了事件处理程序)?作为读者,你有没有想过这个问题?

这个问题涉及浏览器中的事件传播机制。相信大家都听说过事件冒泡和事件捕捉。是的,它们是浏览器中的事件传播机制。没有图片,没有真相,没有图片?那怎么有钱到:

看完图,相信大家已经对浏览器中的事件传播机制有了大致的了解:当事件发生时,会从浏览器顶层对象Window一直向下传输到触发事件的元素,这就是事件捕获过程。但是,一切都没有结束,事件从这个元素一直传递到Window对象,这就是事件冒泡过程(但是在IE8及其之前的版本中,事件模型没有定义捕获过程,只有冒泡过程)。

因此,关于上述问题,这取决于元素A注册的事件处理程序是处于捕获过程中还是冒泡过程中。那么在捕获过程中注册事件处理程序到底是什么,在冒泡过程中注册事件处理程序是如何完成的呢?现在是时候讨论注册事件处理程序的几种方法了:

1.将HTML标记属性设置为事件处理程序。

文档元素的事件处理程序属性的名称由“on”后跟事件名称组成,例如onclick和onmouseover。当然,这个表单只能注册DOM元素的事件处理程序。示例:

!DOCTYPE html html head meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '/title test/title style type=' text/CSS ' # div 1 { width : 300 px;height: 300px背景:红色;飞越:隐藏;} # div2 { margin:50px auto宽度: 200 px;高度: 200 px;背景:绿色;飞越:隐藏;} # div3 { margin:50px auto宽度: 100 px;高度: 100像素;背景:蓝色;}/style/head body div id=' div 1 ' OnClick=' console . log(' div 1 ');'div 1 div id=' div 2 ' OnClick=' console . log(' div 2 ');'div 2 div id=' div 3 ' onclick=' console . log(' div 3 ');'onclick=' console . log(' div 3333 ');'Div3/div/div/div脚本类型=' text/JavaScript '/script/body/html结果(点击Div3区域后):

从结果可以看出:

(1)由于HTML不区分大小写,这里的事件处理程序的属性名可以大写、小写或者混合大小写,属性值为对应事件处理程序的JavaScript代码;

如果为同一个元素编写多个onclick事件处理属性,浏览器将只执行第一个onclick中的代码,后者将被忽略;

在这种形式下,事件处理程序在事件冒泡过程中注册;

2.将JavaScript对象属性设置为事件处理程序。

您可以通过设置事件处理程序属性来为事件目标注册事件处理程序。事件处理程序属性名由“on”后跟事件名组成,例如onclick和onmouseover。示例:

!DOCTYPE html html head meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '/title test/title style type=' text/CSS ' # div 1 { width : 300 px;height: 300px背景:红色;飞越:隐藏;} # div2 { margin:50px auto宽度: 200 px;高度: 200 px;背景:绿色;飞越:隐藏;} # div3 { margin:50px auto宽度: 100 px;高度: 100像素;背景:蓝色;}/style/head body div id=' div 1 ' div 1 div id=' div 2 ' div 2 div id=' div 3 ' div 3/div/div script type=' text/JavaScript ' var div 1=document . getelementbyid(' div 1 ');var div 2=document . getelementbyid(' div 2 ');var div 3=document . getelementbyid(' div 3 ');div 1 . onclick=function(){ console . log(' div 1 ');};div 2 . onclick=function(){ console . log(' div 2 ');};div 3 . onclick=function(){ console . log(' div 3 ');};div 1 . onclick=function(){ console . log(' div 11111 ');};div 1 . onclick=function(){ console . log(' div 11111 ');};/script/body/html结果(鼠标点击div3区域后):

从结果可以看出:

(1)由于JavaScript严格区分大小写,按照这种形式的规定,属性名只能小写;

如果对同一个元素对象写多个onclick事件处理属性,后面的会覆盖前面的(ps:这是修改一个对象属性的值,是唯一确定的);

该表单还注册了事件冒泡过程中的事件处理程序;

3.addEventListener()

前两种方法出现在Web的早期,很多浏览器都实现了。addEventListener()方法是在标准事件模型中定义的。任何可以作为事件目标的对象——,包括Window对象、Document对象和所有文档元素,都定义了一个名为addEventListener()的方法,通过该方法可以为事件目标注册事件处理程序。AddEventListener()接受三个参数:第一个参数是要注册的处理程序的事件类型,其值为字符串,但不包括前缀“on”;第二个参数是指当指定类型的事件发生时应该调用的函数;第三个参数是布尔值,可以忽略(这个参数在一些旧浏览器中不能忽略),默认值是false。在这种情况下,事件处理程序在事件冒泡过程中注册。如果为真,则在事件捕获期间注册事件处理程序。示例:

!DOCTYPE HTMl HTMl heartheta http-equiv=' Content-TYPe ' Content=' text/html;charset=utf-8 '/title test/title style type=' text/CSS ' # div 1 { width : 300 px;height: 300px背景:红色;飞越:隐藏;} # div2 { margin:50px auto宽度: 200 px;高度: 200 px;背景:绿色;飞越:隐藏;} # div3 { margin:50px auto宽度: 100 px;高度: 100像素;背景:蓝色;}/style/head dydiv id=' div 1 ' div 1 div 1 div id=' div 2 ' div 2 div id=' div 3 ' div 3/div/div script type=' text/JavaScript ' var div 1=document . getelementbyid(' div 1 ');var div 2=document . getelementbyid(' div 2 ');var div 3=document . getelementbyid(' div 3 ');div1.addEventListener('click ',function(){ console . log(' div 1-bubble ');},false);div2.addEventListener('click ',function(){ console . log(' div 2-bubble ');},false);div3.addEventListener('click ',function(){ console . log(' div 3-bubble ');},false);div3.addEventListener('click ',function(){ console . log(' div 3-bubble 222 ');},false);div1.addEventListener('click ',function(){ console . log(' div 1-captureing ');},真);div2.addEventListener('click ',function(){ console . log(' div 2-captureing ');},真);div3.addEventListener('click ',function(){ console . log(' div 3-captureing ');},真);/script/body/html结果(鼠标点击div3区域后):

从结果可以看出:

(1) addEventListener()第三个参数的作用如上所述;

通过addEventListener()方法向同一个对象注册多个同类型的事件不会被忽略或覆盖,而是按顺序执行;

与addEventListener()相对的是removeEventListener()方法,该方法也有三个参数,前两个参数的含义与addEventListener()相同,第三个参数只需要与对应的addEventListener()的第三个参数一致即可,也可以省略,默认值为false。这意味着从对象中删除一个事件处理程序。示例:

div1.addEventListener('click ',div1BubbleFun,false);div 1 . removeeventlistener(' click ',div1BubbleFun,false);function div1 bubble fun(){ console . log(' div1-bubble ');}4.attachEvent()

但是,IE8和更早版本的浏览器不支持addEventListener()和removeEventListener()。因此,IE定义了类似的方法attachEvent()和disconnectevent()。attachEvent()无法在捕获过程中注册事件处理程序,因为IE8及其之前的浏览器不支持事件捕获,所以AttachEvent()和disconnectevent()只需要两个参数:事件类型和事件处理程序。此外,它们的第一个参数使用前缀为“on”的事件处理程序属性名。示例:

var div 1=document . getelementbyid(' div 1 ');div1.attachEvent('onclick ',div 1 bubble fun);function div1 bubble fun(){ console . log(' div1-bubble ');}相应地,从对象中移除事件处理函数,并使用discoverent()。例如:

div 1 . separate vent(' onclick ',div 1 bubble fun);到目前为止,我们已经讨论了浏览器中事件传播的机制以及注册事件处理程序的各种方法。我们来谈谈调用事件处理程序时的一些问题。

二.事件处理程序的调用。

1.事件处理程序的参数:如前所述,通常事件对象作为参数传递给事件处理程序,但IE8及其以前的浏览器中的全局变量event就是事件对象。所以在编写相关代码时要注意兼容性。示例(向页面上id为div1的元素添加click事件,并在单击元素时在控制台上输出事件类型和被单击的元素本身):

!DOCTYPE html html head meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '/title test/title style type=' text/CSS ' # div 1 { width : 300 px;高度: 300像素背景:红色;飞越:隐藏;}/style/head body div id=' div 1 ' div 1/div脚本类型=' text/JavaScript ' var div 1=文档。getelementbyid(' div 1 ');if(div 1。addeventlistener){ div 1。addeventlistener(' click ',div1Fun,false);} else if(div 1。attachevent){ div 1。attachevent(' onclick ',div 1 fun);}函数div 1 fun(event){ event=event | | window。事件;var target=事件。目标| |事件。srcelelement控制台。日志(事件。类型);console.log(目标);}/脚本/正文/html2 .事件处理程序的运行环境:关于事件处理程序的运行环境,也就是在事件处理程序中调用上下文(这个值)的指向问题,可以看下面四个实例。

实例一:

!DOCTYPE html html head meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '/title test/title style type=' text/CSS ' # div 1 { width : 300 px;高度: 300像素背景:红色;飞越:隐藏;}/style/head body div id=' div 1 ' onclick=' console。日志'(html : ');'控制台。日志(这个);div1/div脚本类型=' text/JavaScript '/script/body/html结果一:

从结果可以看出:

第一种方法事件处理程序中这指向这个元素本身;

实例二:

!DOCTYPE html html head meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '/title test/title style type=' text/CSS ' # div 1 { width : 300 px;高度: 300像素背景:红色;飞越:隐藏;}/style/head body div id=' div 1 ' onclick=' console。日志'(html : ');'控制台。日志(这个);div1/div脚本类型=' text/JavaScript ' var div 1=文档。getelementbyid(' div 1 ');1区。onclick=function(){ console。日志(' div 1。onclick :’);console.log(此);};/脚本/正文/html结果二:

从结果可以看出:

第二种方法事件处理程序中这也指向这个元素本身;

存在第二种方法时,它会覆盖第一种方法注册的事件处理程序;

实例三:

!DOCTYPE html html head meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '/title test/title style type=' text/CSS ' # div 1 { width : 300 px;高度: 300像素背景:红色;飞越:隐藏;}/style/head body div id=' div 1 ' onclick=' console。日志'(html : ');'控制台。日志(这个);div1/div脚本类型=' text/JavaScript ' var div 1=文档。getelementbyid(' div 1 ');1区。onclick=function(){ console。日志(' div 1。onclick :’);console.log(此);};div1.addEventListener('click ',function(){ console。日志(' div 1。add event listener :’);console.log(此);},false);/脚本/正文/html结果三:

从结果可以看出:

第三种方法事件处理程序中这也指向这个元素本身;

第三种方法并不会覆盖第一种或第二种方法注册的事件处理程序;

实例四:

!DOCTYPE html html head meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '/title test/title style type=' text/CSS ' # div 1 { width : 300 px;高度: 300像素背景:红色;飞越:隐藏;}/style/head body div id=' div 1 ' onclick=' console。日志'(html : ');'控制台。日志(这个);div1/div脚本类型=' text/JavaScript ' var div 1=文档。getelementbyid(' div 1 ');1区。onclick=function(){ console。日志(' div 1。onclick :’);console.log(此);};div1.attachEvent('onclick ',function(){ console。日志(' div 1。attach event :’);console.log(此===窗口);});/脚本/正文/html结果四:

从结果可以看出:

第四种方法事件处理程序中这指向全局对象窗口;

第四种方法也不会覆盖第一种或第二种方法注册的事件处理程序;

3.事件处理程序的调用顺序:多个事件处理程序调用规则如下:

通过超文本标记语言属性注册的处理程序和通过设置对象属性的处理程序一直优先调用;

使用addEventListener()注册的处理程序按照它们的注册顺序依次调用;

向attachEvent()注册的处理程序可以按任意顺序调用,因此代码不应依赖于调用顺序;

4.事件取消:

取消事件的浏览器默认操作(例如,点击超链接元素时页面自动跳转的默认操作):如果使用前两种方法注册了事件处理程序,可以将返回值false添加到处理程序中,取消事件的浏览器默认操作。在支持addEventListener()的浏览器中,还可以通过调用事件对象的preventDefault()方法来取消事件的默认操作。至于IE8及其以前的浏览器,可以通过将事件对象的returnValue属性设置为false来取消事件的默认操作。参考代码:

函数cancelHandler(event){ var event=event | | window . event;if(event . preventdefault){ event . preventdefault();} if(event . return value){ event . return value=false;}返回false} 取消事件传播:在支持addEventListener()的浏览器中,可以调用事件对象的stopPropagation()方法,防止事件继续传播,它可以在事件传播过程中的任何阶段(捕获阶段、事件目标本身、冒泡阶段)工作;但是,在IE8及其之前的浏览器中不支持stopPropagation()的方法,这些浏览器也不支持事件传播的捕获阶段。因此,IE事件对象具有cancelBubble属性,将该属性设置为true可以防止事件的进一步传播(即防止其冒泡)。参考代码(防止div3区域的点击事件冒泡到div2和div1):

!DOCTYPE html html head meta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8 '/title test/title style type=' text/CSS ' # div 1 { width : 300 px;height: 300px背景:红色;飞越:隐藏;} # div2 { margin:50px auto宽度: 200 px;高度: 200 px;背景:绿色;飞越:隐藏;} # div3 { margin:50px auto宽度: 100 px;高度: 100像素;背景:蓝色;}/style/head body div id=' div 1 ' div 1 div id=' div 2 ' div 2 div id=' div 3 ' div 3/div/div/div脚本类型=' text/JavaScript ' var div 1=document . getelementbyid(' div 1 ');var div 2=document . getelementbyid(' div 2 ');var div 3=document . getelementbyid(' div 3 ');div 1 . onclick=function(){ console . log(' div 1 ');};div 2 . onclick=function(){ console . log(' div 2 ');};div 3 . onclick=function(event){ stopeventproads(event);console . log(' div 3 ');};函数stop event propagation(event){ var event=event | | window . event;if(event . stopperpagation){ event . stopperpagation();} else { event.cancelBubble=true}} /script/body/html以上是javascript事件处理的完整介绍。当然,关于事件冒泡还有一些有用的东西,这就是我们常说的事件代理或事件委托。关于这方面的知识以后会陆续更新。

更多资讯
游戏推荐
更多+