带你快速理解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之后就消失了,因此也就不会在执行接下来的事件函数了。

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

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

(0)

相关推荐

  • javascript事件模型代码

    本节稍稍深入地讨论关于事件处理的话题,如果你对模式.闭包和面向对象等概念还不太理解,不妨暂且等阅读完相关内容之后再回过头来阅读它,相信你会有很大收获. 1 事件处理模式 在程序设计领域,"事件处理"是一种模式,当一个对象受外部影响而改变状态时,通过消息的方式将这个状态改变通知给这个对象或者相关联的某个对象,让它执行对应的动作,这就是事件处理的基本原理.负责通知状态改变的对象被称作"消息",而执行响应动作的属性则被称作"事件代理".        

  • javascript事件模型实例分析

    本文实例讲述了javascript事件模型的用法.分享给大家供大家参考.具体分析如下: 一.事件模型 冒泡型事件(Bubbling):事件由叶子节点沿祖先节点一直向上传递到根节点 捕获型事件(Capturing):由DOM树最顶元素一直到最精确的元素,与冒泡型事件相反 DOM标准事件模型:DOM标准既支持冒泡型事件,也支持捕获型事件,可以说是两者的结合体,首先是捕获型,接着冒泡传递 二.事件对象 在IE浏览器中事件对象是window的一个属性,在DOM标准中,event必须作为唯一的参数传给事件

  • javascript 传统事件模型构造的事件监听器实现代码

    代码如下: 复制代码 代码如下: var br={}; br.eventRouter = {}; br.eventRouter.addListen = function(el,eventType,func){ if(!el.eventObjs){ el.eventObjs = {}; } if(!el.eventObjs[eventType]){ el.eventObjs[eventType]=[]; br.eventRouter.bindListen(el,eventType); } el.e

  • javascript事件模型介绍

    一.原始事件模型 其事件类型:分为"输入事件(如onclicki)"和"语义事件(如onsubmit)" 事件程序的注册可以以下几种方式: 1.JS代码作为HTML性质值 复制代码 代码如下: <input type="button" value="Press me" onclick="alert('thanks');" 2.事件处理程序作为JS属性 附注:文档中的每个HTML元素在文档树中都有一个相

  • 事件模型在各浏览器中存在差异

    标准参考 根据 W3C DOM 2 Events 描述,EventTarget 接口被所有支持 DOM 事件模型的节点(Node)实现. 该接口提供了 'addEventListener' 和 'removeEventListener' 方法,用来绑定或解绑一个 EventListeners 接口到一个 EventTarget. DOM 2 Events 中定义了 Event 接口,用来提供事件的上下文信息,它提供了若干标准属性和方法. 实现 Event 接口的对象一般作为第一个参数传入事件处理

  • javascript事件捕获机制【深入分析IE和DOM中的事件模型】

    本文实例分析了javascript事件捕获机制.分享给大家供大家参考,具体如下: 1.什么是事件冒泡? 在排序算法中,我们学过冒泡排序法,所谓冒泡就是让底层的东西浮出水面,对于事件冒泡也同样是如此, 下面我们来看一个例子来说明什么是事件冒泡. <div> <button>测试</button> </div> <script> $("div").bind("click",function(){alert(&q

  • js事件模型与自定义事件实例解析

    JavaScript 一个最简单的事件模型,需要有事件绑定与触发,还有事件删除. var eventModel = { list: {}, bind: function () { var args = [].slice.call(arguments), type = args[0], handlers = args.slice(1); if (typeof type === 'string' && handlers.length > 0) { for (var i = 0; i &l

  • ASP.NET的事件模型(很适合学习的文章)

    在Default.aspx的页面中第一行是一条页面指令: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AspxEventsModel._Default" %> 其中CodeBehind属性指定代码隐藏页面的名称,Inherits指定所属的命名空间和类,AutoEventWireup属性是可以

  • 关于javascript DOM事件模型的两件事

    事件捕捉(Event Capture)的实现问题 W3C DOM Level2的事件模型规范中,事件在DOM树中的传播过程(从根节点到目标节点)被分为了两个阶段:捕捉(Capture)和冒泡(Bubbling).下面这个图能大概的说明整个过程: (from W3C) 如果想创建一个捕捉事件,在支持W3C 事件模型的浏览器中,将addEventListener的第三个参数设为true就好了.例如: 复制代码 代码如下: document.getElementById('foo').addEvent

  • Javascript基础知识(一)核心基础语法与事件模型

    一.Javascript核心基础语法 1.Javascript是一门增加交互效果的编程语言,它最初由网景公司发明,最后提交给ECMA(欧洲计算机制造商协会),ECMA将Javascript标准化,其命名为Javascript. 2.Javascript是一门解释性语言,无需编译就可以直接在浏览器下运行. 3.Javascript的用途? 1.可以控制网页中所有元素,增加.删除.修改元素的属性. 2.可以在html中放入动态文本. 3.响应用户在使用网页时产生的事件. 4.校验用户输入的数据. 5

  • js DOM模型操作

    DOM模型中的节点:元素节点.文本节点.属性节点 例:<a href="http://www.cnblogs.com/shuz">私のdotnet小屋</a> (1)a是元素节点 (2)"私のdotnet小屋"是文本节点 (3)href="http://www.cnblogs.com/shuz"是属性节点 DOM节点的属性 属性 类型 说明 nodeName String 节点名称,根据节点的类型而定义 nodeValue

随机推荐