当浏览器发展到第四代时候,浏览器开发团队遇到了一个有意思的问题;页面的哪一部分会拥有某个特地的事件?要明白这个问题问的是什么,可以想象画在纸上的一组同心圆,如果你把手指放在圆心上,那么你的手指指向的不是一个圆,而是纸上所有的圆。两家公司的开发团队在这件事情上的看法是一致的,如果你单击了某个按钮,他们都认为单击事件不仅发生在按钮上,更是发生在了整个容器元素,甚至是整个页面。

那么对于页面接收事件的顺序两者出现了不同的定义:捕获流 ( chrome )冒泡流( IE )。在事件监听addEventListener的第三个参数中,捕获流是 true,冒泡流是 false。主流浏览器默认的都是冒泡流机制,也就是第三个参数默认false。

事件捕获:window -> document -> html -> body -> button  (原先的‘DOM2级事件’本来是规定事件应该从document对象出发的,但是后面几乎所有的浏览器还是拓展到了window对象层面)

事件冒泡:button -> body -> html -> document -> window

事实上‘DOM2级事件’规定的事件流包括了三个阶段: 事件捕获阶段,处于目标阶段,事件冒泡阶段。(原先是规定捕获阶段不涉及事件目标的,但是后面高版本都会在捕获阶段触发事件对象上的事件)

重点:处于目标阶段,即button的事件在捕获阶段和冒泡阶段都会被触发。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.box
{
position: relative;
background-color: coral;
border: 1px solid;
padding: 50px;
}
.child {
position: relative;
background-color: pink;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="A" class="box">
<div id="B">
<div id="C" class="child">点击该方块, 我是冒泡</div>
</div>
</div><br>
<script>
document.getElementById("A").addEventListener("click", function(e)
{
console.log("1 捕获");
}, true);
document.getElementById("B").addEventListener("click", function(e)
{
console.log("2 捕获");
// e.stopPropagation()
}, true);
document.getElementById("C").addEventListener("click", function(e)
{
console.log("捕获阶段触发目标");
// e.stopPropagation()
}, true);
document.getElementById("C").addEventListener("click", function()
{
console.log("冒泡触发目标");
}, false);
document.getElementById("B").addEventListener("click", function()
{
console.log("1 冒泡");
}, false);
document.getElementById("A").addEventListener("click", function()
{
console.log("2 冒泡");
}, false); </script> </body>
</html>

  

 

执行结果如下:

值得注意的是,捕获阶段或者冒泡阶段对应的在 C 上的事件其实并不是 先捕获阶段触发目标 然后是冒泡阶段触发目标,在C上的事件其实是都是触发的,触发顺序取决于你写的顺序。不信,换下顺序如下

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.box
{
position: relative;
background-color: coral;
border: 1px solid;
padding: 50px;
}
.child {
position: relative;
background-color: pink;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="A" class="box">
<div id="B">
<div id="C" class="child">点击该方块, 我是冒泡</div>
</div>
</div><br>
<script>
document.getElementById("A").addEventListener("click", function(e)
{
console.log("1 捕获");
}, true);
document.getElementById("B").addEventListener("click", function(e)
{
console.log("2 捕获");
// e.stopPropagation()
}, true);
document.getElementById("C").addEventListener("click", function()
{
console.log("冒泡触发目标");
}, false);
document.getElementById("C").addEventListener("click", function(e)
{
console.log("捕获阶段触发目标");
// e.stopPropagation()
}, true); document.getElementById("B").addEventListener("click", function()
{
console.log("1 冒泡");
}, false);
document.getElementById("A").addEventListener("click", function()
{
console.log("2 冒泡");
}, false); </script> </body>
</html>

执行结果如下:

接下来继续说一下阻止冒泡,假设我在  console.log("1 捕获") 或者 console.log("2 捕获") 后面加上  e.stopPropagation(),后面的事件还能触发吗?单单是只把冒泡流扼杀了吗?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.box
{
position: relative;
background-color: coral;
border: 1px solid;
padding: 50px;
}
.child {
position: relative;
background-color: pink;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="A" class="box">
<div id="B">
<div id="C" class="child">点击该方块, 我是冒泡</div>
</div>
</div><br>
<script>
document.getElementById("A").addEventListener("click", function(e)
{
console.log("1 捕获");
e.stopPropagation()
}, true);
document.getElementById("B").addEventListener("click", function(e)
{
console.log("2 捕获"); }, true);
document.getElementById("C").addEventListener("click", function()
{
console.log("冒泡触发目标");
}, false);
document.getElementById("C").addEventListener("click", function(e)
{
console.log("捕获阶段触发目标");
// e.stopPropagation()
}, true); document.getElementById("B").addEventListener("click", function()
{
console.log("1 冒泡");
}, false);
document.getElementById("A").addEventListener("click", function()
{
console.log("2 冒泡");
}, false); </script> </body>
</html>

  

事实上,它是把后面的事件流都打断了。而如果 e.stopPropagation() 是写在  console.log("捕获阶段触发目标") 或者  console.log("冒泡触发目标")后面,目标阶段都点击事件都会执行,执行按你写的顺序来。

Propagation英文意思是‘传播’ stopPropagation 就是阻止事件传播,阻止事件流的继续往下发生。

所以stopPropagation()方法事实上是打断了事件流继续执行,而我们一般时候是直接写在目标事件的点击函数里,就起到了阻止冒泡的作用!

  

js的事件流你真的弄明白了吗?的更多相关文章

  1. js的事件流理解

    面试问到js的事件流,当时说的不是很清楚,现在觉得有必要把这个弄清楚. 事件捕获和事件冒泡 事件流描述的是从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序. 事件流主要分为两种,即事件捕获和事 ...

  2. js基础--javaScript数据类型你都弄明白了吗?绝对干货

    欢迎访问我的个人博客:http://www.xiaolongwu.cn 数据类型的分类 JavaScript的数据类型分为两大类,基本数据类型和复杂数据类型. 基本数据类型:Null.Undefine ...

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

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

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

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

  5. 前端 ----js的事件流的概念(重要)

    09-JS的事件流的概念(重点)   在学习jQuery的事件之前,大家必须要对JS的事件有所了解.看下文 事件的概念 HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件.页 ...

  6. JS的事件流的概念(重点)

      09-JS的事件流的概念(重点)   在学习jQuery的事件之前,大家必须要对JS的事件有所了解.看下文 事件的概念 HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件 ...

  7. JS的事件流的概念

    事件的概念: HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件.页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件.想要知道这些事件是在 ...

  8. JS的事件流概念*******

    事件的概念 HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件.页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件. 事件流 事件流描述的 ...

  9. 08 JS的事件流的概念(重点)

    在学习jQuery的事件之前,大家必须要对JS的事件有所了解.看下文 事件的概念 HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件.页面的滚动事件onscroll等等,可以 ...

随机推荐

  1. Linux防火墙命令

    linux 查看防火墙状态   1.查看防火墙状态 systemctl status firewalld firewall-cmd --state #查看默认防火墙状态(关闭后显示notrunning ...

  2. 纯CSS的三角符号

    项目中经常用到三角形,现在给大家讲下用纯CSS写的下三角实心图形 .triangle{ border-width: 5px 4px 0 4px; border-color: #454A7B trans ...

  3. Python 动态加载 Extension Manager Classes

    看着看着发现了一个库:stevedore(http://stevedore.readthedocs.org/en/latest/managers.html),但是感觉文档做得不行啊,都没个tutori ...

  4. 我为什么不用Django而用Flask?

    前言 对于初学者来说,找到一个好的框架来学习或者项目开发都是非常有必要的,而当你有一定开发经验后,你应该选择适合当前业务需要的框架.我这里并不想探讨哪个框架好哪个不好,这个永恒的话题就跟探讨“世界上哪 ...

  5. H5手机页面剖析

    <!--强制使用webkit内核进行渲染--><meta http-equiv="X-UA-COMPATIBLE" content="IE=edge, ...

  6. SharePoint 2013 - Designer Workflow

    另一篇文章 SharePoint Designer - Workflow 1. 可以定义每个Stage的名称,并将Stage名称显示在工作流状态字段,相比于SP2010时仅有的in progress ...

  7. CentOS安装chrome-浏览器

    首先,在CentOS中安装软件,通过yum命令来安装软件,就要在系统中的软件源中添加软件源节点,即在目录./etc/yum.repos.d/下的CentOS-Base.repo文件中做修改:在控制台C ...

  8. mvc页面间的传值

    本文大致讲解mvc前后端的传值方式,包括control向view.view向control.以及action向action. 回顾 我们回顾下在ASP.NET WebForms中,页面之间最常用的传值 ...

  9. SQL Server ->> 查看SQL Server备份历史

    找到最近数据库备份的细节信息,包括备份设备名和地址,最后备份时间 ------------------------------------------------------------------- ...

  10. python:Non-ASCII character ‘\xe2′ in file

    python 2.7系列的  在运行.py文件时 报错python:Non-ASCII character ‘\xe2′ in file 解决办法:  在文件顶部 加入  #  coding: utf ...