1.何为DOM

DOM是“Document Object Model”的缩写,中文译为“文档对象模型”。它是一种跨平台、跨语言的编程接口,将HTML,XHTML,XML文档映射成树形结构,树的每一个节点都是一个对象。正因如此,面向对象的编程语言(如javascript)可以通过DOM对HTML,XHTML,XML文档进行操作。对于HTML文档来说,它的根结点为document对象,HTML元素为element对象,HTML元素的属性为attr对象。

2.何为DOM事件及如何对其作出响应

在浏览网页时,我们常常需要页面对用户的操作作出响应,比如点击“阅读全文”后我们期望页面展示被折叠的文本,按下回车键后浏览器提交已填好的表单。用户的各种操作都是“事件”。事件都是在对象上发生的,可能是DOM对象、BOM对象,等等。事件发生后,对象可能会作出响应,也有可能“无动于衷”。我们希望DOM元素对事件作出响应,一般而言有两种方法:
i.事件属性
事件属性是一种特殊的属性,它的值规定了对应事件发生时需要执行的javascript脚本。例:

```<button onclick="console.log('button clicked!')"></button>
```

上面为button标签添加了事件属性onclick,其值为"console.log('button clicked!')",它规定了当元素被鼠标点击时,控制台输出'button clicked'。
ii.addEventListener()方法
EventTarget.addEventListener()方法将指定的监听器注册到EventTarget上,当该对象触发指定的事件时,指定的回调函数就会被执行。EventTarget可以是element对象,document对象或者任何其他支持事件的对象。例:

```<!--html文件中-->
<button id='mybutton'></button>
```


//脚本中
var mybutton=document.getElementById('mybutton');
mybutton.addEventListener('click',function(e){console.log('button clicked!');});

上例为button元素注册了click事件的监听器,并规定事件时触发控制台输出'button clicked'。

3.DOM事件模型

在讲解DOM事件模型前,再用一个例子作为引入。请看下面的html文件:

```<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DOM Event Model</title>
<style>
div{position: absolute;}
#outer{
top: 100px;
left: 100px;
width: 600px;
height: 400px;
background-color: #aff;
}
#inner1,#inner2{
top: 50px;
width: 200px;
height: 300px;
background-color: #f9a;
}
#inner1{left: 50px;}
#inner2{left: 350px;}
#core{
left: 50px;
top: 50px;
width: 100px;
height: 150px;
background-color: #f50;
}
</style>
</head>
<body>
<div id='outer' onclick="console.log(this.id)">
<div id='inner1' onclick="console.log(this.id)"></div>
<div id='inner2' onclick="console.log(this.id)">
<div id='core' onclick="console.log(this.id)"></div>
</div>
</div>
</body>
</html>
```

这里为id分别为outer,inner1,inner2,core的4个元素定义了事件属性,元素被点击后将在控制台输出它的id。现在问题来了:
如果我点击core元素,控制台将会输出什么?
点击core元素时,由于core元素包含在inner2元素里,inner2元素同样被点击了;同理,inner2元素包含在outer元素里,那么outer元素也被点击了。这种情况下哪一个元素的click事件将会被触发,或者说三者都被触发?如果说三者都被触发,那么又是以怎样的顺序被触发?
我在火狐浏览器做了一次实验,控制台输出结果如下:

```core
inner2
outer
```

也就是说,三者的事件都被触发了,且是“由内向外”触发的。
下面我们再做一个有趣的实验:我们将上面的html文件再做一个小小的改动,将core元素的样式


left: 50px;

改为


left: -250px;

此时观察页面我们会发现,尽量core是inner2的子节点,但由于我们定义了“怪异”的样式,它跑到了inner1里面。现在我们再次用鼠标点击core,观察控制台的输出:

```core
inner2
outer
```

和刚才的结果一模一样!尽管表面上inner1似乎被点击了,但它的click事件并没有触发;反而是看似未被点击的inner2元素的click事件被触发了。仿佛core元素的click事件被触发后,click事件一层一层向上“传播”给了父节点。
为了解释刚才的实验结果,是时候开始讲解DOM事件模型了。
当一个事件发生时,事件会在DOM树中进行传播。传播分为两个阶段:
i.捕获阶段
在此阶段,事件从根结点(即document结点)开始向下传播,直到事件源所在元素。
ii.冒泡阶段
在此阶段,事件从事件源开始向上传播,直到根结点。
拿刚才的例子来说,事件传播的顺序为:
document捕获->html捕获->body捕获->outer捕获->inner2捕获->core捕获->core冒泡->inner2冒泡->outer冒泡->html冒泡->document冒泡
对于事件属性,默认在冒泡阶段触发事件。如果用addEventListener()方法注册监听器,则可以指定在捕获阶段还是冒泡阶段触发事件:如果最后一个参数为false(默认值),则在冒泡阶段触发事件;如果为true,则在捕获阶段触发事件。
一般来说,我们推荐采用addEventListener()方法来注册监听器,而尽量不用事件属性。因为事件属性不利于行为与结构的分离,使代码难以维护。

原文地址:https://segmentfault.com/a/1190000016748916

DOM事件模型浅析的更多相关文章

  1. javascript中0级DOM和2级DOM事件模型浅析

    Javascript程序使用的是事件驱动的设计模式,为一个元素添加事件监听函数,当这个元素的相应事件被触发那么其添加的事件监听函数就被调用: <input type="button&q ...

  2. javascript中0级DOM和2级DOM事件模型浅析 分类: C1_HTML/JS/JQUERY 2014-08-06 15:22 253人阅读 评论(0) 收藏

    Javascript程序使用的是事件驱动的设计模式,为一个元素添加事件监听函数,当这个元素的相应事件被触发那么其添加的事件监听函数就被调用: <input type="button&q ...

  3. W3C DOM 事件模型(简述)

    1.事件模型 由于事件捕获与冒泡模型都有其长处和解释,DOM标准支持捕获型与冒泡型,能够说是它们两者的结合体.它能够在一个DOM元素上绑定多个事件处理器,而且在处理函数内部,thiskeyword仍然 ...

  4. JavaScript DOM事件模型

    早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的JavaScript的实现都不进相同,本节内容介绍JavaScript的DOM事件模型及事件处理程序的分类. 1.DOM事件模型.DO ...

  5. DOM事件: DOM事件级别、DOM事件流、DOM事件模型、DOM事件捕获过程、自定义事件

    前端面试中只要问到事件,就肯定会有DOM事件:如果回答出来了,就会一直向下延申,其实这些东西都很简单,但我第一次被问到的时候,也是懵的: DOM事件级别: DOM0 element.onclick = ...

  6. JavaScript DOM 事件模型

    JavaScript DOM 事件模型 JavaScript 是基于面向对象和事件驱动的一门语言,事件模型是 DOM 中至关重要的内容,理解事件驱动机制.事件反馈.事件冒泡.事件捕获以及事件委托能帮助 ...

  7. DOM 事件深入浅出(一)

    在项目开发时,我们时常需要考虑用户在使用产品时产生的各种各样的交互事件,比如鼠标点击事件.敲击键盘事件等.这样的事件行为都是前端DOM事件的组成部分,不同的DOM事件会有不同的触发条件和触发效果.本文 ...

  8. 【repost】JavaScript 事件模型 事件处理机制

    什么是事件? 事件(Event)是JavaScript应用跳动的心脏 ,也是把所有东西粘在一起的胶水.当我们与浏览器中 Web 页面进行某些类型的交互时,事件就发生了.事件可能是用户在某些内容上的点击 ...

  9. 标准事件模型和IE事件模型有哪些区别?请具体解释他们的差异。

    通常,事件传送有三个阶段:事件捕获阶段,停留目标阶段,事件冒泡阶段. 1.阶段差异 DOM事件模型包含捕获阶段和冒泡阶段,DOM事件模型可使用e.stopPropagation()来阻止事件流:IE事 ...

随机推荐

  1. 最新的vue没有dev-server.js文件,如何进行后台数据模拟?

    最新的vue里dev-server.js被替换成了webpack-dev-conf.js 在模拟后台数据的时候直接在webpack-dev-conf.js文件中修改 第一步,在const portfi ...

  2. AVL树(自平衡二叉查找树)

    了解AVL树之前要先了解二叉查找树(BST),BST查找元素的时间复杂度平均是O(logN),最坏的情况是O(N),所有的元素都接在左子树(或者右子树)就相当于一串链表了.而AVL树会对子树过高的情况 ...

  3. JAVA 7新特性——在单个catch代码块中捕获多个异常,以及用升级版的类型检查重新抛出异常

    在Java 7中,catch代码块得到了升级,用以在单个catch块中处理多个异常.如果你要捕获多个异常并且它们包含相似的代码,使用这一特性将会减少代码重复度.下面用一个例子来理解. Java 7之前 ...

  4. 利用arguments对象在javaScript中实现重载(overload)

    一些概念: 重载(overload): 什么是: 相同函数名,不同参数列表的多个函数,在调用时,可根据传入参数的不同,自动选择对应的函数调用! 为什么: 减轻调用者的负担,一个函数名,可执行多种操作 ...

  5. Jasper_table_resolve multiple copies of table in detail band issue

    resolve method: (1) put table component into the Title band / Page Header band / Summary band, not i ...

  6. datagridview连接数据库的简单实现

    对于需要从数据库获取数据的列,在DataPropertyName填写对应的列名字. 在Load函数中添加如下代码,先关闭自动生成列选项,然后得到一个查询的datatable,并将其绑定到datasou ...

  7. JavaScript Allongé 第一呷 :基础函数 (2)

    啊!我想要有一个参数 到现在为止,我们已经了解了没有参数的函数.只说我们的函数没有任何参数,甚至还没说参数是什么.大多数程序员非常熟悉参数,中学数学就讨论这个了.所以你知道他们是什么,而我也知道你知道 ...

  8. TDH-kafka

    一.kafka原理:1.broker:一个kafka实例,多个broker组成kafka集群: 2.topic:逻辑概念,同一类数据的集合,可以看做一张表: 3.producer:将数据写入topic ...

  9. nodejs 不是单线程

    nodejs 不是单线程 在我机器上,nodejs 起了近 20 个线程. 对,你没有看错,20个线程.

  10. drupal中文安装指导

    (注:drupal6中文包放在profiles/default/translations下,drupal7放在profiles/standard/translations下) Drupal 6 中文安 ...