DOM 事件相关知识总结——事件绑定、事件流(事件冒泡、捕获)

2023-11-09

1. 事件绑定方式

1. 直接给元素添加事件属性

<input  onclick="alert('我被点击了!')"  type="button"  value="点我试试" />

优点:大家都会,几乎所有的浏览器都支持

缺点:夹杂在HTML代码中,代码不简洁;这种事件写法效率不高;不符合“行为,样式,结构”相分离。

2. js中赋值事件

<button id="btn">点我</button>
<script>
  var btn = document.getElementById("btn");
  btn.onclick = function() {
    console.log("事件触发")
  }
  
// 事件解绑
btn.onclick = null
</script>

优点:符合“行为,样式,结构”相分离;便于操作当事对象;方便读取事件对象

缺点: 只能给一个元素注册一个相同事件,绑定多个相同事件,后一个会覆盖前一个

  var btn = document.getElementById("btn");
  btn.onclick = function() {
    console.log("事件触发1")
  }
  btn.onclick = function() {
    console.log("事件触发2")
  }
// 事件触发1

3. 事件监听 addEventListener()

<button id="btn">点我</button>
<script>
  var btn = document.getElementById("btn");
  btn.addEventListener("click", function () { 
    console.log("事件触发");
  });
 
// 事件解绑
btn.removeEventListener("click", function () { 
    console.log("事件解绑触发");
})
</script>

addEventListener第三个参数,Boolean类型值,可指定事件冒泡阶段还是捕获阶段触发,true-捕获,false-冒泡,默认false,既冒泡。

优点:可以注册多个相同时间,后面的事件不会被覆盖

<button id="btn">点我</button>
<script>
  var btn = document.getElementById("btn");
  btn.addEventListener("click", function () { 
    console.log("事件触发1");
  });
  btn.addEventListener("click", function () { 
    console.log("事件触发2");
  });
</script>
// 事件触发1
// 事件触发2

缺点: 写法相对复杂

2. DOM事件流

DOM事件流(event flow )存在三个阶段:

  1. 事件捕获阶段
  2. 处于目标阶段
  3. 事件冒泡阶段。
    事件流模型,记为 洋葱模型(先外到内,再内到外)
事件捕获(由外到内):

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

事件冒泡(有内到外):

与事件捕获恰恰相反,事件冒泡顺序是由内到外进行事件传播,直到根节点。

dom标准事件流的触发的先后顺序为:先捕获再冒泡,即当触发dom事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。不同的浏览器对此有着不同的实现,IE10及以下不支持捕获型事件,所以就少了一个事件捕获阶段,IE11、Chrome 、Firefox、Safari等浏览器则同时存在。

实践:

<body>
<div id="box1">
    <span>box1</span>
    <div id="box2">
        <span>box2</span>
        <div id="box3"><span>box3</span></div>
    </div>
</div>

<script>
    var box1 = document.getElementById("box1");
    var box2 = document.getElementById("box2");
    var box3 = document.getElementById("box3");
    //给每个元素添加点击事件

    box1.onclick = function () {
        console.log("事件冒泡——box1");
    };

    box2.onclick = function () {
        console.log("事件冒泡——box2");
    };

    box3.onclick = function () {
        console.log("事件冒泡——box3");
    };

    box1.addEventListener("click", function () {
        console.log("事件捕获——box1");
    }, true);

    box2.addEventListener("click", function () {
        console.log("事件捕获——box2");
    }, true);

    box3.addEventListener("click", function () {
        console.log("事件捕获——box3");
    }, true);

</script>
</body>

当点击 box3 的后,会先由外到内开始进行捕获阶段,然后有内到外开始冒泡阶段
在这里插入图片描述

取消事件捕获、事件冒泡

 	var box1 = document.getElementById("box1");
    var box2 = document.getElementById("box2");
    var box3 = document.getElementById("box3");
    //给每个元素添加点击事件

    box1.onclick = function () {
    	e.stopPropagation();
        console.log("事件冒泡——box1");
    };

    box2.onclick = function () {
    	e.stopPropagation();
        console.log("事件冒泡——box2");
    };

    box3.onclick = function () {
    	e.stopPropagation();
        console.log("事件冒泡——box3");
    };

    box1.addEventListener("click", function () {
    	e.stopPropagation();
        console.log("事件捕获——box1");
    }, true);

    box2.addEventListener("click", function () {
    	e.stopPropagation();
        console.log("事件捕获——box2");
    }, true);

    box3.addEventListener("click", function () {
    	e.stopPropagation();
        console.log("事件捕获——box3");
    }, true);

stopPropagation与stopImmediatePropagation区别:

1. stopPropagation:

阻止事件像外冒泡

<div id="root">
   <div id="box"></div>
</div>
<script>
  var root = document.getElementById("root");
  var box = document.getElementById("box");
  box.addEventListener("click", function (event) { 
    event.stopPropagation();
    console.log("box-事件触发1");
  });
  box.addEventListener("click", function () { 
    console.log("box-事件触发2");
  });
  root.addEventListener("click", function () { 
    console.log("root-事件触发");
  });
</script>
// box-事件触发1
// box-事件触发2
2. stopImmediatePropagation:

阻止后面相同元素事件触发

<div id="root">
   <div id="box"></div>
</div>
<script>
  var root = document.getElementById("root");
  var box = document.getElementById("box");
  box.addEventListener("click", function (event) { 
    event.stopImmediatePropagation();
    console.log("box-事件触发1");
  });
  box.addEventListener("click", function () { 
    console.log("box-事件触发2");
  });
  root.addEventListener("click", function () { 
    console.log("root-事件触发");
  });
</script>
// box-事件触发1
// root-事件触发

事件冒泡的作用——事件委托

<body>
<div id="box">
    <p class="hehe">我是文本内容</p>
    <p class="hehe">我是文本内容</p>
    <p>我是文本内容</p>
    <span>我是span的内容</span>
</div>


<script>
    //事件委托
    //我们需要根据冒泡的元素不同,进行筛选,只有p标签才能够执行事件
    //第一步添加box的事件
    box.onclick = function (e) {
        e.stopPropagation()
        //需要获取,当前这个事件是由哪一个子元素触发的
        //第二步 兼容事件对象e
        var e = e || window.event;

        //第三步 兼容取出触发事件的元素的方式  target srcElement
        var tar = e.target || e.srcElement;

        //第四步 检测tar是什么标签
//        if (tar.nodeName.toLowerCase() == "p") {
        if (tar.nodeName.toUpperCase() == "P") {
            console.log("呵呵,我是p的代码");
        }
    };

    //可以通过nodeName属性获取到元素的标签名
    console.log(box.nodeName);
</script>
</body>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DOM 事件相关知识总结——事件绑定、事件流(事件冒泡、捕获) 的相关文章

随机推荐

  • 程序分析

    程序分析 百科名片 程序分析是指对 计算机程序行为进行自动分析的过程 主要包括静态分析和动态分析两种策略 目录 简介 什么是程序分析 程序分析的目的 程序分析的种类及图表 程序分析的记录符号 程序分析的技巧 程序分析的实施及步骤 程序分析的
  • 后渗透中提权的必要性和思路

    很多同学常常问起 渗透测试中获取服务器权限后一定要提权吗 为什么要提权呢 故有此文 提权的必要性 在一场完整的渗透测试中 如果已经获取服务器权限 此时就进入后渗透阶段了 渗透的最终目的是获取服务器的最高权限 即windows操作系统中管理员
  • 牛客网_剑指Offer_Python实现_更新中

    剑指Offer编程题汇总 第1题 二维数组中的查找 第2题 替换空格 第3题 从尾到头打印链表 第4题 重建二叉树 第5题 用两个栈实现队列 第6题 旋转数组的最小数字 第7题 斐波那契数列 第8题 跳台阶 第9题 变态跳台阶 第10题 矩
  • 计算圆周率

    根据用户输入计算圆周率 import math import random def type judge pi type 接收一个字符串为参数 根据参数调用相应函数计算圆周率 if pi type 割圆法 times int input 输
  • StringBuffer 和StringBuilder的应用场景

    StringBuffer线程安全 StringBuilder线程不安全 StringBuffer比StringBuilder慢 网络上有很多的文章有说到他们两个的区别 以及应用场景 这里说下个人感悟 StringBuffer更多会和修改全局
  • 伯努利分布、二项分布、泊松分布、指数分布、Gamma分布的联系

    伯努利分布 0 1分布 伯努利分布是二项分布在N 1时的特例 随机变量为取值为0或者1 二项分布 N次重复且独立的伯努利实验 随机变量为在N次实验中出现某种情况 概率为p 的次数K 泊松分布 二项分布的极限形式 N趋于无穷大 P趋于0 描述
  • 工具:语雀导出MarkDown文档后图片修复

    微信公众号 乌鸦安全 扫取二维码获取更多信息 01 描述 在比较早的时候 我比较纠结记笔记的产品 最初的时候是在使用Typora在本地写Markdown文档 后来试用了一下印象笔记 但是它的缺点就是贵 而且上传的流量很少 在之后氪金的一刹那
  • 从一张表数据选出,插入另外一张表

    在CSDN搜到一篇博文原文如下 今天在做数据库操作的时候 有一个需求是将A表中的前500000条数据查出来 然后插入到表B中 表A与表B具有同样的字段类型 数据库为Oracle 10g 数据库管理工具用的PL SQL 由于数据库不是特别的熟
  • vue中使用WebSocket(ui用的ant design)

    那些原理 和什么情况下时候适合用WebSocket我这就不多说 直接上代码 哈哈 拷贝即用
  • fast虚拟服务器地址,fast虚拟服务器地址

    fast虚拟服务器地址 内容精选 换一换 参数说明如下 VPC网段 VPC的地址范围 根据规划的子网信息 配置VPC的地址范围 子网网段 VPC中默认子网的地址范围 需要在VPC的子网地址范围内 根据规划的信息进行配置 DNS服务器地址 默
  • 多个Livox雷达点云合成及使用ROS发布

    项目场景 因为单个Livox avia的FOV只有70 无法覆盖车前方的所有范围 所以用了三个Livox avia以实现180 前方位覆盖 但由于三个雷达均是独自采集 所以需要对每个雷达采集的各帧点云进行合并 用于建图 以下工作均建立于已经
  • [C进阶] 数据在内存中的存储——整形篇

    前言 学习一门语言就像是了解一个陌生人 首先我们要做的是从外貌和举止来宏观上考察一个人的特点 然后逐渐的对其进行深入了解 最终变得知根知底 畅所欲言 本章我们对数据存储的探讨其实就是在对C语言进行深入了解 因为只有知根知底才能畅所欲言 本章
  • 路由器选择使用指南这三Openwrt

    一 关于Openwrt 嗯 这个和华硕没什么关系 虽然也是亲戚 同样源于linux 所以linux最牛 关于这个固件可以说的就多了 前面padavan比较水 这个多写点 Openwrt有很多大神小神毛神小白在为它编译固件 说到这个就不得不提
  • CEF使用的几个注意点

    转自http www cnblogs com gongxijun p 4857977 html CEF为chrome浏览器的切入其他浏览器中的轻量级框架 开发的客户端的时候 这是作为界面显示的首先 可以增强客户的易变性 可塑性 在开发的过程
  • 计算机网络中的泊松分布与指数分布

    一 概率论知识 1 1 泊松分布 一个时间段里某件事发生的概率 用泊松分布来描述 1 2 指数分布 两个事件的间隔时间为某个值的概率 用指数分布来描述 1 3 两者关系 其中 服从泊松分布的事件 其间隔时间服从指数分布 二 计算机网络知识
  • 深度学习撞墙了?

    转自 机器之心 早在 2016 年 Hinton 就说过 我们不用再培养放射科医生了 如今几年过去 AI 并没有取代任何一位放射科医生 问题出在哪儿 近年来 AI 在大数据 大模型的深度学习之路上一路狂奔 但很多核心问题依然没有解决 比如如
  • redis监控指标

    服务器系统数据采集 Redis Server数据采集 Redis响应时间数据采集 Redis监控Screen b b b 一 服务器存活监控 1 gt ping监控告警 2 gt CPU 3 gt 丢包率 b 二 Redis Server监
  • 使用数字陷波器滤除工频信号

    在实际测量时经常会受到工频信号 交流50Hz 的干扰 有时干扰还很大 有用信号完全被淹没了 可以应用数字陷波器来消除工频信号的干扰 数字陷波器函数如下 函数 iirnotch 功能 数字陷波器设计 调用格式 b a iirnotch Wo
  • vscode报错:SyntaxError: Cannot use import statement outside a module

    报错内容 E workspace2 cronmall ui npmdemo modulees61 02 js 2 import getList save from 01 js SyntaxError Cannot use import st
  • DOM 事件相关知识总结——事件绑定、事件流(事件冒泡、捕获)

    1 事件绑定方式 1 直接给元素添加事件属性