先看下面的示例代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>JavaScript 中的事件冒泡与事件捕获</title>
</head>
<body>
<div id="Red" style="width:200px;height:200px;background-color:red;padding:20px;">
<div id="Bule" style="width:160px;height:160px;background-color:blue;padding:20px;">
<div id="Yellow" style="width:120px;height:120px;margin:auto;background-color:yellow;padding:20px;">
<div id="Green" style="width:80px;height:80px;margin:auto;background-color:green;padding:20px;"></div>
</div>
</div>
</div>
</body>
</html>

效果如下图所示:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQEAAAD7CAIAAADl8LZhAAADzElEQVR4nO3TMY4bQRAEwX26fk69QM4VRLIvo5FuATNGPC/n2vd8+gHOffgYcPVjwNWPAVe/fxt4Hun3xIDqMaB6DKgeA6rHgOoxoHoMqB4DqseA6jGgegyoHgOqx4DqMaB6DKgeA6rHgOoxoHoMqN6bDXz8v/qVbWMGdL9tzIDut40Z0P22MQO63zZmQPfbxgzoftuYAd1vGzOg+21jBnS/bcyA7reNGdD9tjEDut82ZkD328YM6H7bmAHdbxszoPttYwZ0v23MgO63jRnQ/bbxHQOv16NfHAMM1GOAgXoMMFCPAQbqMcBAPQYYqMcAA/UYYKAeAwzUY4CBegwwUI8BBuoxwEA9BhioxwAD9RhgoB4DDNRjgIF6DDBQj4H/a+D5o3fEAAP1GGCgHgMM1GOAgXoMMFCPAQbqMcBAPQYYqMcAA/UYYKAeAwzUY4CBegwwUI8BBuoxwEA9BhioxwAD9RhgoB4DDNRjgIF6DDBQjwEG6jHAQD0GGKjHAAP1GGCgHgMM1GOAgXoMMFCPAQbqMcBAPQYYqMcAA/UYYKAeAwzUY4CBegwwUI8BBuoxwEA9BhioxwAD9RhgoB4DDNRjgIF6DDBQjwEG6jHAQD0GGKjHAAP1GGCgHgMM1GOAgXoMMFCPAQbqMcBAPQYYqMcAA/UYYKAeAwzUY4CBegwwUI8BBuoxwEA9BhioxwAD9RhgoB4DDNRjgIF6DDBQjwEG6jHAQD0GGKjHAAP1GGCgHgMM1GOAgXoMMFCPAQbqMcBAPQYYqMcAA/UYYKAeAwzUY4CBegwwUI8BBuoxwEA9BhioxwAD9RhgoB4DDNRjgIF6DDBQjwEG6jHAQD0GGKjHAAP1GGCgHgMM1GOAgXoMMFCPAQbqMcBAPQYYqMcAA/UYYKAeAwzUY4CBegwwUI8BBuoxwEA9BhioxwAD9RhgoB4DDNRjgIF6DDBQjwEG6jHAQD0GvteAvj8GGKjHAAP1GGCgHgMM1GOAgXoMMFCPAQbqMcBAPQYYqMcAA/UYYKAeAwzUY4CBegwwUI8BBuoxwEA9BhioxwAD9RhgoB4D0s/bxgzoftuYAd1vGzOg+21jBnS/bcyA7reNGdD9tjEDut82ZkD328YM6H7bmAHdbxszoPttYwZ0v23MgO63jRnQ/bYxA7rfNmZA99vGDOh+25gB3W8bM6D7beP3GpC+LgZUjwHVY0D1GFA9BlSPAdVjQPUYUD0GVI8B1WNA9RhQPQZUjwHVY0D1GFA9BlSPAdVjQPV+YsC5xjHg6seAqx8Drn4MuPox4Or3FzMgflDKJklaAAAAAElFTkSuQmCC" alt="" />

考虑这种情况,我们用鼠标点击最中间的 绿色,触发了绿块DIV的点击事件,那是不是也触发了它的父级 黄色块的点击事件,以及祖先级别的 蓝色以及红色块的点击事件?

早期的浏览器开发商网景以及微软一致的认为该点击事件确实触发了父级和祖先级别的点击事件!!!

一、事件流

事件流描述的是从页面中接收事件的顺序,虽然IE以及Netscape都承认事件流的存在,但是却提出了差不错完全相反的事件流概念。IE的事件流是 事件冒泡流,而Netscape的事件流是 事件捕获流。

二、事件冒泡流

事件冒泡流的意思就是事件会从最开始触发的那个元素开始,一级级的向上传播并触发祖先级别对应的事件,直至Document 对象为止。

因此如果我们点击图中的绿色块 click 事件发生的顺序应该是 Green -> Yellow -> Blue -> Red -> body -> html -> document。

三、事件捕获流

事件捕获流与事件冒泡流相反,事件会从最外层开始触发,直至最具体的元素为止。

因此如果我们点击图中的绿色块 click 事件发生的顺序应该是 document -> html -> body -> Red -> Blue -> Yellow -> Green。

四、事件流的实现

W3C的 “DOM2级事件” 中规定的事件流同时支持了事件捕获阶段和事件冒泡阶段。我们可以使用 “DOM2级事件” 提供的两个方法 addEventListener()和 removeEventListener()  来为一个特定的元素绑定或者删除一个事件处理函数:

element.addEventListener(event, function, useCapture)

element.removeEventListener(event, function, useCapture)

event : 要处理的事件名

function:事件处理程序的函数

useCapture:布尔值 指定使用哪种事件流。false 采用事件冒泡流,true 采用事件捕获流。

请看以下 JavaScript 代码:

<script type ="text/javascript">
var div = document.getElementsByTagName("div");
for (var i = 0; i < div.length; i++)
{
div[i].addEventListener("click", showColor, false); // false 代表冒泡事件流, true 代表捕获事件流
} function showColor()
{
alert("触发的DIV的颜色是: " + this.id);
}
</script>

点击最里面的绿色块

当 addEventListener(event, function, useCapture) 的 useCapture 参数为 false 时,依次弹出 Green Yellow Blue Red。

当 addEventListener(event, function, useCapture) 的 useCapture 参数为 true时,依次弹出 Red Blue Yellow Green。

题外记:

今天试了另外一段 JS 代码:

<script type ="text/javascript">
var div = document.getElementsByTagName("div");
for (var i = 0; i < div.length; i++)
{
var useCapture = true;
if (i%2==0)
useCapture = false
;
div[i].addEventListener("click", showColor, useCapture); // false 代表冒泡事件流, true 代表捕获事件流
} function showColor()
{
alert("触发的DIV的颜色是: " + this.id);
}
</script>

注意我加粗加红的那段代码,分别给几个div设置了不同的 useCapture.

再次点击绿色块Green时,依次弹出的是 Blue Green Yellow Red.

是因为我们给 Blue块和Green块设置的 useCapture 的值为true 即 事件捕获. Yellow块和Red块依然是 false 即 冒泡事件.

当我们点击绿色块Green时,会先找其祖先级别元素中采用 事件捕获 的元素,一直捕获到当前的元素,然后接着冒泡,但会跳过 事件捕获 的元素,一直到document.

总结起来就一句话: 任何发生在 W3C  “DOM2级事件” 中的事件,首是进入捕获阶段,直到达到目标元素,再进入冒泡阶段。

  

JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获的更多相关文章

  1. JS Event事件流(冒泡机制、捕获机制、事件绑定)

    1.事件流 事件流:从页面中接收事件的顺序.也就是说当一个事件产生时,这个事件的传播过程,就是事件流. IE的事件流 IE中的事件流叫事件冒泡:事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播 ...

  2. WPF教程六:理解WPF中的隧道路由和冒泡路由事件

    WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由事件能更好的处理事件相关的逻辑,我们从这篇开始整理事件的用法和什么是直接路由,什么是冒泡路由,以及什么是隧道路由. 事件最基本的用法 ...

  3. js事件流机制冒泡和捕获

    JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间. 事件流 从页面中接收事件的顺序称为事件流. IE --> 事件冒泡流 Netsc ...

  4. python 全栈开发,Day55(jQuery的位置信息,JS的事件流的概念(重点),事件对象,jQuery的事件绑定和解绑,事件委托(事件代理))

    一.jQuery的位置信息 jQuery的位置信息跟JS的client系列.offset系列.scroll系列封装好的一些简便api. 一.宽度和高度 获取宽度 .width() 描述:为匹配的元素集 ...

  5. 关于DOM事件流、DOM0级事件与DOM2级事件

    一.DOM 事件模型 DOM 事件模型包括捕获和冒泡,捕获是从上往下到达目标元素,冒泡是从当前元素,也就是目标元素往上到 window 二.流 流的概念,在现今的 JavaScript 中随处可见.比 ...

  6. 【事件流】浅谈事件冒泡&&事件捕获------【巷子】

    首先在扯淡的时候我们需要先了解一个东西,这个东西就是事件流. 1.什么是事件流? 解释:当一个HTML元素触发一个事件处理函数的时候,该事件会在该元素节点到根节点之间传播,传播路径所经过的节点都会接受 ...

  7. 在javascript中的浏览器兼容问题以及兼容浏览器汇总(默认事件,阻止冒泡,事件监听。。。)以及解决方式详解

    在javascript中常见的浏览器兼容问题,以及解决方式. 在前端工作当中我们遵循这样的原则:渐进增强和优雅降级   渐进增强(progressive enhancement): 针对低版本浏览器进 ...

  8. [已转移]IE事件流和DOM标准事件流的区别

    该文章已转移到博客:https://cynthia0329.github.io/ 1.执行的顺序不一样 冒泡型事件模型: button->div->body (IE事件流) 捕获型事件模型 ...

  9. Dom事件流、冒泡、捕获

    Dom事件流 dom的结构是一个倒立的树状结构.当一个html元素触发事件时,事件会在dom的根节点和触发事件的元素节点之间传播,中间的节点都会收到该事件. 捕获:div元素触发事件时,事件先从根节点 ...

随机推荐

  1. 点击不同按钮生成不同窗体到某个panel上面,类似Frame用法--不错

    //点击不同按钮生成不同页面加载到某个panel上面.procedure TMainForm.DemoButtonClick(Sender: TObject); var NewDemoClass: T ...

  2. jquery笔记(效果)

    显示/隐藏: $(selector).hide(speed, function()):隐藏 $(selector).show(speed, function()):隐藏 $(selector).tog ...

  3. three.js右手坐标系, 显示和线条

    1.右手坐标系 Threejs使用的是右手坐标系,这源于opengl默认情况下,也是右手坐标系.下面是右手坐标系的图例,如果对这个概念不理解,可以百度一下,我保证你伸出手比划的那一瞬间你就明白了,如果 ...

  4. oracle去重

    oracle去重 create table tmp_table3 as (SELECT seqno FROM (SELECT t.seqno,ROWID, ROW_NUMBER() OVER(PART ...

  5. ural 1143. Electric Path

    1143. Electric Path Time limit: 1.0 secondMemory limit: 64 MB Background At the team competition of ...

  6. unity 解析tmx 2

    using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; usin ...

  7. BZOJ4471 : 随机数生成器Ⅱ

    \[\begin{eqnarray*}x_i&=&x_{i-1}+x_{i-2}\\x_i^2&=&x_{i-2}^2+x_{i-1}^2+2x_{i-2}x_{i-1 ...

  8. 【BZOJ】1987: Zju2672 Fibonacci Subsequence

    题意 给出一个序列\(A\),求一个最长的满足fib性质的子序列,输出其长度及其元素(如果多种方案,输出位置最靠前的).(\(n \le 3000\)) 题解 容易想到dp,即\(d(i, j)\)表 ...

  9. Codeforces Round #210 (Div. 2) C. Levko and Array Recovery

    题目链接 线段树的逆过程,想了老一会,然后发现应该是包含区间对存在有影响,就不知怎么做了...然后尚大神,说,So easy,你要倒着来,然后再正着来,判断是不是合法就行了.然后我乱写了写,就过了.数 ...

  10. ThinkPHP 分页类的使用及退出功能的实现

    /* ThinkPHP设置编码统一: 一.数据库设置为utf8_bin 二.HTML页面设置charset=utf-8,而且检查文档编码格式是否是utf-8.phpDesigner8设置方式为“文件- ...