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. IP服务-2-RARP和BOOTP

    ARP和代理ARP进程都是在一台主机知道了自己的IP地址和子网掩码后发生的.RARP.BOOTP和DHCP则代表了一类协议的发展,这类协议用来帮助主机动态地学习自己的IP地址.

  2. JQuery数组遍历 - $.each(),$().each()和forEach()

  3. C# 基础之索引器

    当一个类有数组成员时,索引器将大大简化对类中数组成员的访问 索引器类似于属性有get与set访问器 列如: 使用: 总结:从以上代码可以看出索引器也是对私有字段进行访问的方式,但此时的私有字段是数组类 ...

  4. [软件工程基础]PhyLab 功能规格说明书

    前言 Sigma 团队想要在 PhyLab 上做的增量改进见需求分析.六个功能中只有题库和图文流程需要对界面进行大的改动,剩下的功能在用户看来仅仅是在原有界面上有内容上的扩充,因此不在功能规格说明书的 ...

  5. ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) D

    Moriarty has trapped n people in n distinct rooms in a hotel. Some rooms are locked, others are unlo ...

  6. 083 Remove Duplicates from Sorted List 有序链表中删除重复的结点

    给定一个排序链表,删除所有重复的元素使得每个元素只留下一个.案例:给定 1->1->2,返回 1->2给定 1->1->2->3->3,返回 1->2- ...

  7. JS脚本不能执行

    这段时间在做前端的动态页面,出了很多问题,因为js平时用的很少,所以花了不少无用功. 其中有两点一定要注意: 1.当js中有语法错误时,js脚本会无法执行. 2.当js脚本中有未定义的变量时,后边的语 ...

  8. Linux网路命令netstat

    Linux网路命令netstat netstat命令是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表.实际的网络连接以及每一个网络接口设备的状态信息. 参数 参数 用法 详解 -a或--a ...

  9. 我的NopCommerce之旅(4): 定时任务之邮件

    一.功能简介 用户购买物品生成订单后,系统将发送邮件提醒给用户 二.操作步骤 后台配置一个系统的默认发送邮箱 启动定时任务,这里包括多个任务,只需要启动邮件任务 查看邮件发送情况 三.数据库分析 [d ...

  10. 解析Javascript事件冒泡机制(转)

    本文转自:http://blog.csdn.net/luanlouis/article/details/23927347 1. 事件 在浏览器客户端应用平台,基本生都是以事件驱动的,即某个事件发生,然 ...