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

那么对于页面接收事件的顺序两者出现了不同的定义:捕获流 ( 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. oracle OTT 学习

    1.OTT概念 OTT 是 Object Type Translator 的缩写,对象类型转换器.它是用来将数据库中定义的类型(UDT)转换为C结构体类型的工具.借助OTT 可以用C语言调用OCI来访 ...

  2. 多结果集IMultipleResult接口

    在某些任务中,需要执行多条sql语句,这样一次会返回多个结果集,在应用程序就需要处理多个结果集,在OLEDB中支持多结果集的接口是IMultipleResult. 查询数据源是否支持多结果集 并不是所 ...

  3. asp: AJAX Database

    <% @LANGUAGE="VBSCRIPT" CODEPAGE="65001" %> <!DOCTYPE html PUBLIC " ...

  4. html-标题标签、水平线标签和特殊字符

    标题标签  <h1></h1> <h2></h2> ...... <h6></h6> 从h1到h6,大小是依次变小,同时会自动换 ...

  5. JavaScript中8个容易犯的错误

    这里dbestech针对JavaScript初学者给出一些技巧和列出一些陷阱. 1. 你是否尝试过对数组元素进行排序? JavaScript默认使用字典序(alphanumeric)来排序.因此,[1 ...

  6. asp.net中<input type=button>无法调用后台函数

    例如:用<input id="bt1" type="button" runat="server" Onclick="btnL ...

  7. 【JS 综合】JS综合

    视频教程链接:http://www.xuexi111.com/s/javascript/ 张孝祥:http://www.21edu8.com/pcnet/programming/26685/

  8. matlab练习程序(Arnold图像置乱)

    自从上次写了Hilbert图像置乱之后,就对图像置乱研究了一下,发现这里面也是有很多置乱算法的. Arnold也算一种比较主要的置乱算法,算法由以下变换公式产生: 这里a和b是参数,n是迭代次数,N是 ...

  9. 【Leetcode】【Easy】Pascal's Triangle

    Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Retur ...

  10. VueJs - 世界地图(根据返回国家value值的大小来展示颜色的深浅分布)

    一.实现功能 1.画出世界各国的世界地图 2.根据返回name->国家全称.value->数量,渲染对比世界各国成功的国家,予以值域范围的高亮 3.滑入国家地图,出现tooltip框,提示 ...