当前位置:首页 > 日记 > 正文

带你快速理解javascript中的事件模型

带你快速理解javascript中的事件模型

javascript中有两种事件模型:DOM0,DOM2。而对于这两种的时间模型,我一直不是非常的清楚,现在通过网上查阅资料终于明白了一些。

  一.  DOM0级事件模型

  DOM0级事件模型是早期的事件模型,所有的浏览器都是支持的,而且其实现也是比较简单。代码如下:

<p id = 'click'>click me</p><script> document.getElementById('click').onclick = function(event){  alert(event.target); }</script>

  这种事件模型就是直接在dom对象上注册事件名称,这段代码就是在p标签上注册了一个onclick事件,在这个事件函数内部输出点击的目标。而解除事件则更加简单,就是将null复制给事件函数,如下:

document.getElementById('click'_).onclick = null;
  由此我们可以知道dom0中,一个dom对象只能注册一个同类型的函数,因为注册多个同类型的函数的话,就会发生覆盖,之前注册的函数就会无效。

var click = document.getElementById('click');click.onclick = function(){ alert('you click the first function');};click.onclick = function(){ alert('you click the second function')}

  在这段代码中,我们为dom对象注册了两个onclick函数,但是结果是只执行了第二个注册的函数,前面所注册的函数被覆盖了。

  二.   DOM2级事件模型

  1.  事件捕获和事件冒泡(capture,bubble)

  首先,IE8及以下是不支持这种事件模型的。事件捕获和事件冒泡的机制如下图:

  如上图所示,123代表事件捕获,4567代表事件冒泡。首先我们使用下面的代码:

<div id = 'outer' style = 'margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'> <div id="inner" style = 'margin-left:20px; width: 50px;height:50px; background: green;'></div></div>


  假设我们点击了ID为inner的div,那么此时的事件流程就是,首先执行捕获阶段:document-html-body-div(outer)。然后执行冒泡阶段:div(inner)-div(outer)-body-html-document。

  2.   DOM2级的注册事件和解除事件

  在DOM2级中使用addEventListener和removeEventListener来注册和解除事件(IE8及之前版本不支持)。这种函数较之之前的方法好处是一个dom对象可以注册多个相同类型的事件,不会发生事件的覆盖,会依次的执行各个事件函数。

  addEventListener('事件名称','事件回调','捕获/冒泡')。示例如下:

<div id = 'outer' style = 'margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'> <div id="inner" style = 'margin-left:20px; width: 50px;height:50px; background: green;'></div></div><script> var click = document.getElementById('inner'); click.addEventListener('click',function(){  alert('click one'); },false); click.addEventListener('click',function(){  alert('click two'); },false);</script>

  首先我们要知道addEventListenr的第一个参数是事件名称,与DOM0级不同的是没有”on“,另外第三个参数代表捕获还是冒泡,true代表捕获事件,false代表冒泡事件。

  而在这段代码中,我们为inner的div注册了两个click事件函数,结果是浏览器会依次执行这两个函数。
  下面我们演示如何使用事件流的发生机制。

<div id = 'outer' style = 'margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'> <div id="inner" style = 'margin-left:20px; width: 50px;height:50px; background: green;'></div></div><script> var click = document.getElementById('inner'); var clickouter = document.getElementById('outer'); click.addEventListener('click',function(){  alert('inner show'); },true); clickouter.addEventListener('click',function(){  alert('outer show'); },true);</script>

  这段代码,我们使用了捕获事件,由于inner是嵌套在outer中的,所以我们知道当使用捕获的时候outer是应该首先捕获到这个事件的,其次inner才能捕获到这个事件。那么结果就是outer首先执行,其次是inner执行。

  那么我把outer的执行时机改为冒泡的阶段呢?

alickouter.addEventListener('click',function(){ alert('outer show'); },false);

  这种情况下,就是先执行inner后执行outer了。同理我们把二者的事件执行时机都改为冒泡阶段的话,依旧是先执行inner后执行outer。那么还有个问题,就是如果我们把inner注册两个click事件,一个是在捕获阶段,另一个是在冒泡阶段,也就是说把addEventListenter的第三个参数分别设置为false和true,那么执行的顺序又是怎样的呢。

<script> var click = document.getElementById('inner'); var clickouter = document.getElementById('outer'); click.addEventListener('click',function(){  alert('capture show'); },true); click.addEventListener('click',function(){  alert('bubble show'); },false);</script>

  这种情况下首先这些的是capture show,其次是bubble show。但是这种结果是与注册的顺序有关系的,先注册就先执行。因为我们在看事件捕获和事件冒泡示意图,发现最后具体的dom对象是只有一个的。

  那么 如果我们给outer和inner都注册了click事件但是我不希望outer执行怎么办呢?这个时候我们就需要用到stopPropagation函数了,这个函数是用来阻止冒泡,言下之意是让事件不再继续冒泡下去,这样接下来注册同样类型事件的dom对象就不会执行了。

比如在自制下拉框的时候,我们点击浏览器的其他位置,我们需要下拉框的options隐藏,这时我们就要用到stopPropagation了。如下:

<script> var click = document.getElementById('inner'); var clickouter = document.getElementById('outer'); click.addEventListener('click',function(event){  alert('inner show');  event.stopPropagation(); },false); clickouter.addEventListener('click',function(){  alert('outer show'); },false);</script>

  正常的情况下,我们在不添加stopPropagation函数时,首先应该执行inner,然后执行outer,但是当我们在inner的事件函数中添加了stopPropagation函数之后,执行完inner的事件函数之后,就不会在执行outer的事件函数了,也可以理解为事件冒泡到inner之后就消失了,因此也就不会在执行接下来的事件函数了。

  由于事件捕获阶段没有可以阻止事件的函数,所以一般都是设置为事件冒泡。

好了以上就是全部内容啦 ,希望对大家的学习有所帮助~~

相关文章

excel 计算常数以E为底的指数函数

excel 计算常数以E为底的指数函数

教程,计算,指数函数,数以,电脑软件,  在Excel中经常需要用到公式函数进行数据统计,其中一个计算以E为底的指数函数,虽然不常用,但学到的也是自己掌握的,接下来是小编为大家带来的excel 计算常数以E为底的指数函数教程,供大家参考。excel 计算…

PHP 信号管理知识整理汇总

PHP 信号管理知识整理汇总

信号,管理知识,电脑软件,PHP,SIGQUIT 建立CORE文件终止进程,并且生成core文件SIGILL 建立CORE文件 非法指令SIGTRAP 建立CORE文件 跟踪自陷SIGBUS 建立CORE文件 总线错误SIGSEGV 建立CORE文件 段…

Jquery中.bind | 、.live | 、.del

Jquery中.bind | 、.live | 、.del

详解,区别,电脑软件,bind,Jquery,简介最近了解到很多网页开发者对jquery中的 .bind() .live() .delegate() 和 .on() 方法存在很多的疑惑。这些疑惑通常是关于它们之间真正的区别是什么啊,什么时候该使用它们啊。下面本文将给大家详细介绍这…

cdr怎么给制作水彩画效果?

cdr怎么给制作水彩画效果?

水彩画,效果,电脑软件,cdr,cdr中想要制作水彩画效果的图片,该怎么制作呢?下面我们就来看看详细的教程。软件名称:CorelDRAW X6 官方简体中文精简绿色便携版软件大小:176MB更新时间:2016-03-181、打开CorelDRAW软件,新建一个空白的文件,鼠标左键单…

怎么在Excel表格设置有效的的日期

怎么在Excel表格设置有效的的日期

日期,输入,设置,表格,电脑软件,  在excel表格中输入指定的日期,为了防止输入错误的日期,我们可以给表格设置输入范围。以下是小编为您带来的关于Excel表格设置有效的的日期输入范围,希望对您有所帮助。Excel表格设置有效的的日期输入范围1、…

微信小程序点击控件修改样式实例详

微信小程序点击控件修改样式实例详

控件,修改,详解,样式,实例,微信小程序点击控件修改样式实例详解现在要在微信小程序中实现点击控件修改样式,如下:微信小程序中不支持直接操作dom,要实现这种效果,我们需要通过设置data,然后利用数据和界面的双向绑定来实现它。第一步:在wxss中定…

Node.js dgram模块实现UDP通信示例

Node.js dgram模块实现UDP通信示例

示例代码,模块,电脑软件,js,Node,1、什么是UDP?这里简单介绍下,UDP,即用户数据报协议,一种面向无连接的传输层协议,提供不可靠的消息传送服务。UDP协议使用端口号为不同的应用保留其各自的数据传输通道,这一点非常重要。与TCP相比,占用资源更少,传…

Photoshop CC 2018内置滤镜camera

Photoshop CC 2018内置滤镜camera

分享,滤镜,一键,技巧,电脑软件,今天给大家分享使用Photoshop CC 2018的内置滤镜camera raw一键磨皮小技巧,它的速度非常非常快,可以说真正的有效步骤只有一步,适用于对于非商业用途、不要求太多细节的图片,效果还是很棒的。这个分享涉及到camer…

ppt2010有布尔运算吗

ppt2010有布尔运算吗

布尔运算,方法,绘制图形,电脑软件,  图形的布尔运算,说白了就是图形之间的加、减法。在其他图形处理软件中布尔运算很常见,但是ppt中暂时还没有把图形的布尔运算放在菜单中。下面给大家分享PPT2010绘制图形布尔运算的方法,欢迎大家来到学习…

解决安装WampServer时提示缺少msvc

解决安装WampServer时提示缺少msvc

提示,文件,安装,电脑软件,WampServer,今天开始学习PHP,对于初学者来说,我们一定希望从简单的开始,所以,从集成环境非常好的WampServer的安装开始.1、下载WampServer安装程序,安装完毕后会出现一个错误.如下:2、这是因为你的电脑缺少c++环境。你…

vue-resource 拦截器使用详解

vue-resource 拦截器使用详解

拦截器,详解,电脑软件,vue,resource,在vue项目使用vue-resource的过程中,临时增加了一个需求,需要在任何一个页面任何一次http请求,增加对token过期的判断,如果token已过期,需要跳转至登录页面。如果要在每个页面中的http请求操作中添加一次判断…

浅谈nodejs中的类定义和继承的套路

浅谈nodejs中的类定义和继承的套路

继承,类定义,套路,浅谈,电脑软件,javascript是一门极其灵活的语言。灵活到你无法忍受!我个人喜欢强类型的语言,例如c/c++,c#等。但是js代表着未来,所以需要学习。js中类定义以及继承有n多种方式,现在来学习一下nodejs类定义以及继承的固定套路…