在js中存在事件冒泡与事件捕获两种概念,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题。

事件冒泡(dubbed bubbling)

事件冒泡我们从字面意思理解就是当用户行为触发我们页面的定义好的事件后,会有一个由内到外的一个冒泡过程,而不是一下子就命中事件绑定的元素

事件捕获(event capturing)

事件捕获与冒泡恰恰相反,当鼠标点击或者触发dom事件时,浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,如果父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件

我们用代码来理解一下

在下边这个例子中,如果两个元素都有一个click的处理函数,那么我们怎么才能知道哪一个函数会首先被触发呢?为了解决这种脑壳痛的问题,就有了今天的主题冒泡与捕获

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JS事件处理程序</title>
<link href="https://cdn.bootcss.com/skeleton/2.0.4/skeleton.min.css" rel="stylesheet">
</head> <body>
<div class="wrapper" id="wrapper">
<div class="container">
<button id="event">JS事件处理程序</button>
</div>
</div> <script>
var wrapper = document.getElementById("wrapper"),
event = document.getElementById("event"); wrapper.addEventListener("click", function () {
alert("1");
console.log("1");
}, true)
event.addEventListener("click", function () {
alert("2");
console.log("2");
}, true)
wrapper.addEventListener("click", function () {
alert("3");
console.log("3");
}, false)
event.addEventListener("click", function () {
alert("4");
console.log("4");
}, false)
</script>
</body> </html>

上面的代码最终输出结果为:

  • 1

  • 2

  • 4

  • 3

在DOM2级事件规定的时间流包括 三个阶段:

  • 事件捕获阶段

  • 处于目标阶段

  • 事件冒泡阶段

我们可以看到addEventListener的第三个参数我们传入的不同,也就是上面结果为什么没有顺序执行的原因,这里我们在来回顾一下addEventListener

addEventListener

语法: target.addEventListener(type, listener[, useCapture])
useCapture 可选Boolean, 当useCapture为true 事件句柄在捕获阶段执行,也就是事件由外向内执行 当useCapture为false 事件句柄在冒泡阶段执行,也就是事件由内向外执行

看到这也应该了解上面代码为何会输出1243了

好了,回来业务中,实际应用场景我们肯定不愿同时触发多个click, 在点击子元素时我们不想触发父元素的事, 这个时候我们就可以使用stopPropagation来停止事件冒泡

代码理解

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JS事件处理程序</title>
<link href="https://cdn.bootcss.com/skeleton/2.0.4/skeleton.min.css" rel="stylesheet">
</head> <body>
<div class="wrapper" id="wrapper">
<div class="container">
<button id="event">JS事件处理程序</button>
</div>
</div> <script> var wrapper = document.getElementById("wrapper"),
event = document.getElementById("event"); wrapper.onclick = function () {
console.log('捕获阶段执行父元素wrapper的事件处理程序')
} event.onclick = function () {
// 阻止事件冒泡
e.stopPropagation()
console.log('冒泡阶段执行子元素event的事件处理程序')
} </script>
</body> </html>

上面的示例中我们使用了stopPropagation来阻止冒泡,所以此时只会触发一个事件了

总结

  • 事件冒泡由内向外执行

  • 事件传播由外向内执行

  • addEventListener的第三个参数可以改变事件流的状态

  • 使用stopPropagation可以阻止冒泡

JS事件冒泡与事件捕获怎么理解?的更多相关文章

  1. JS事件(事件冒泡和事件捕获)

    事件流:描述的是在页面中接收事件的顺序 事件冒泡:由最具体的元素接收,然后逐级向上传播至最不具体的元素的节点(文档) 事件捕获:最不具体的节点先接收事件,而最具体的节点应该是最后接收事件 DOM中:用 ...

  2. js 事件冒泡和事件捕获

    事件流:指的是网页中元素接受事件的顺序,它是一个概念,而不是具体的实际的东西 事件冒泡:指的是内层元素的事件,会触发包含着此元素的外层元素的事件,触发的顺序是:由内而外的 例如: <!DOCTY ...

  3. 彻底弄懂JS的事件冒泡和事件捕获(不推荐阅读)

    由于搬去敌台了,好久没来博客园,今天无意中翻到有“误认子弟”的评论,这里特意做个说明. 本文中关于事件冒泡和事件捕获的描述和例子都是OK的,错就错在后面用jquery去展示了利用事件冒泡的例子有误,其 ...

  4. js进阶 12-2 彻底弄懂JS的事件冒泡和事件捕获

    js进阶 12-2 彻底弄懂JS的事件冒泡和事件捕获 一.总结 一句话总结:他们是描述事件触发时序问题的术语.事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件.相反的,事件 ...

  5. 浅谈js的事件冒泡和事件捕获

    本文地址:https://www.cnblogs.com/christineqing/p/7607113.html 前言:    这篇文章起源于上次工作上的原因,在事件上出的bug,所以就抽空写出一篇 ...

  6. JS中的事件绑定,事件捕获,事件冒泡以及事件委托,兼容IE

    转载请注明出处:http://www.cnblogs.com/zhangmingze/p/4864367.html   ● 事件分为三个阶段:   事件捕获 -->  事件目标 -->   ...

  7. 彻底弄懂JS的事件冒泡和事件捕获

      先上结论:在事件执行流中有两种执行方式.一种是事件冒泡(即事件的执行顺序是从下往上执行的) ;  另一种是捕获(即事件的执行顺序是从上往下执行的); 阻止事件冒泡:   return false; ...

  8. js高级:event,事件冒泡,事件捕获

    1.事件 浏览器客户端上客户触发的行为都称为事件 所有的事件都是天生自带的,不需要我们去绑定,只需要我们去触发. 通过 obj.事件名=function(){} 事件名:onmouseover 鼠标悬 ...

  9. JS高级:事件冒泡和事件捕获;

    1.事件:浏览器客户端上客户触发的行为成为时事件:所有的事件都是天生自带的,不需要我们去绑定,只需要我们去触发 当用户触发一个事件时,浏览器的所有详细信息都存在一个叫做event的对象上,我们把它叫做 ...

随机推荐

  1. Express中间件原理详解

    前言 Express和Koa是目前最主流的基于node的web开发框架,他们的开发者是同一班人马.貌似现在Koa更加流行,但是仍然有大量的项目在使用Express,所以我想通过这篇文章说说Expres ...

  2. 【leetcode】653. Two Sum IV - Input is a BST

    Given the root of a Binary Search Tree and a target number k, return true if there exist two element ...

  3. Output of C++ Program | Set 7

    Predict the output of following C++ programs. Question 1 1 class Test1 2 { 3 int y; 4 }; 5 6 class T ...

  4. 【Linux】【Services】【SaaS】Docker+kubernetes(12. 部署prometheus/grafana/Influxdb实现监控)

    1.简介 1.1. 官方网站: promethos:https://prometheus.io/ grafana:https://grafana.com/ 1.2. 架构图 2. 环境 2.1. 机器 ...

  5. Maven错误收集

    Eclipse 创建项目时报错 Could not resolve archetype org.apache.maven.archetypes:maven-archetype-quickstart:1 ...

  6. 注解开发中的@Results注解使用

    package com.hope.dao;import com.hope.domain.User;import com.sun.xml.internal.bind.v2.model.core.ID;i ...

  7. Python初探——sklearn库中数据预处理函数fit_transform()和transform()的区别

    敲<Python机器学习及实践>上的code的时候,对于数据预处理中涉及到的fit_transform()函数和transform()函数之间的区别很模糊,查阅了很多资料,这里整理一下: ...

  8. 利用docker-compose一键部署

    利用docker-compose一键部署 目录 利用docker-compose一键部署 前言 快速编写微服务 common-api nacos-server-provider nacos-serve ...

  9. 什么是甘特图(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 名词解释:"甘特图(Gantt Chart)是一种图形化的项目活动及其他相关系统进度情况的水平方向的条状图.&q ...

  10. 【论文笔记】Leveraging Post-click Feedback for Content Recommendations

    Leveraging Post-click Feedback for Content Recommendations Authors: Hongyi Wen, Longqi Yang, Deborah ...