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

news2025/1/15 23:47:15

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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/419395.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

79-Linux_Socket实现客户端与服务器端间通讯

Socket实现客户端与服务器端间通讯一.网络编程的接口1.socket2.bind3.listen4.accept5.connect6.close7.ssize_t recv和ssize_t send8.UDP 数据读写二.tcp流式服务和粘包问题三.客户端及服务器端实现的代码.1.客户端2.服务器端一.网络编程的接口 头文件: #include <sys/typ…

win11使用移动硬盘(固态非固态)卡顿问题解决

以前win10使用移动硬盘没用出现过卡顿的问题&#xff0c;后来更新win11后&#xff0c;硬盘在处理文件和文件新建以及编辑的时候&#xff0c;都会莫名其妙卡1-3秒左右。以为是盘坏了&#xff0c;各种检测和修复。发现没有问题 后来还找移动硬盘的商家沟通&#xff0c;也无果打算…

C语言基础应用(四)选择结构

引言&#xff1a; 在日常生活中&#xff0c;我们时时刻刻面临着选择&#xff0c;在C语言中&#xff0c;如果我们需要判断条件从而实现不同的要求&#xff0c;我们就需要使用选择结构。 注&#xff1a;以下代码均未导入头文件&#xff0c;如果读者使用了代码&#xff0c;请记得…

day9 条件变量的基本使用

目录 条件变量 条件变量 应用场景&#xff1a;生产者消费问题&#xff0c;是线程同步的一种手段&#xff1b; 必要性&#xff1a;为了实现等待某个资源&#xff0c;让线程休眠&#xff0c;提高运行效率&#xff1b; 等待资源&#xff1a; //1、一直等待资源 int pthread_c…

linux 匿名文件 memfd_create

专栏内容&#xff1a;linux下并发编程个人主页&#xff1a;我的主页座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物&#xff0e;目录 前言 概述 原理 接口 代码演示 结尾 前言 本专栏主要分享linux下并发编程相关知识…

慌了!ChatGPT吃我饭,还要掀我碗?

ChatGPT面世&#xff0c;各种被AI取代“失业言论”笼罩在人们头顶&#xff0c;本文聚焦这一问题&#xff0c;推荐关注ChatGPT的小伙伴阅读。 一时间火爆全网的新晋网红——ChatGPT&#xff0c;就问&#xff1a;还有谁不认识&#xff1f; 谷歌计划在旗舰搜索引擎中添加对话式人…

TCP/UDP协议 (详解)

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

网络安全之入侵检测

目录 网络安全之入侵检测 入侵检测经典理论 经典检测模型 入侵检测作用与原理 意义 异常检测模型&#xff08;Anomaly Detection&#xff09; 误用检测模型&#xff08;Misuse Detection&#xff09; 经典特征案例 ​编辑自定义签名 ​编辑 签名检查过程 检测生命周期…

提升 Prometheus 的高可用性:Thanos 的部署与实践!

背景 在高可用 prometheus&#xff1a;问题集锦文章中有简单提到 Prometheus 的高可用方案&#xff0c;尝试了联邦、Remote Write 之后&#xff0c;我们最终选择了 Thanos 作为监控配套组件&#xff0c;利用其全局视图来管理我们的多地域、300集群的监控数据。本文主要介绍 Th…

NC237662 葫芦的考验之定位子串(SAM + 后缀链接树上倍增)

题意&#xff1a; 给出一个字符串S&#xff0c;|S| ≤ 250000&#xff0c;给出 Q < 250000 次询问&#xff0c;每次需要回答 S[l, r] 在 S 中共出现了多少次。 思路&#xff1a; 如果使用 SAM&#xff0c;我们提前求出每个状态的 cnt[u]&#xff0c;询问就是要求我们快速…

Nuxt3中的中间件-middleware

参考&#xff1a;nuxt3中间件(middleware)详解 - 简书nuxt3中间件(middleware)详解 在项目中有时候需要在网站切换路由的过程中添加一些自定义的逻辑&#xff0c;比如权限什么的。这个时候可以使用nuxt的middleware。 ...https://www.jianshu.com/p/bd22637c6447 中间件的作用…

【算法系列之动态规划】子序列篇

300.最长递增子序列 力扣题目链接 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1…

Ubunutu18.04+Qt5.14+Dlib19.24+Opencv3.4.16实时人眼监测实验

文章目录1 前言2 效果3 Ubuntu18.04下Qt、Opencv、Dlib的配置3.0 Ubuntu18.04的安装以及一些基本配置3.1 Qt3.2 Opencv3.3 Dlib4 核心代码4.1 pro文件4.2 Widget.cpp4.3 fatiguedetect.cpp5 资源下载1 前言 在Ubuntu18.04实现的一个人眼监测小程序&#xff0c;使用Qt5.14、Dlib…

仿京东放大镜效果的实现

仿京东放大镜 &#xff08;1&#xff09; 整个案例可以分为三个功能模块 &#xff08;2&#xff09; 鼠标经过小图片盒子&#xff0c; 黄色的遮挡层 和 大图片盒子显示&#xff0c;离开隐藏2个盒子功能 &#xff08;3&#xff09;黄色的遮挡层跟随鼠标功能。 &#xff08;4&…

百度文心一言与Notion的比较(机器人通信的例子)

文心一言出来有一段时间了&#xff0c;也经常会去问问&#xff0c;感觉对于简单的语义理解还是可以&#xff0c;其答案对于一些常见的常识等还是可以给出不错的答案&#xff0c;但是在数学与代码等方面基本上很差&#xff0c;基本的贷款利率、微积分、没有理解语义的代码等都是…

一篇五分生信临床模型预测文章代码复现——Figure 10.机制及肿瘤免疫浸润(一)

之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…

C++篇 ---- 命名空间namespace

由于在c语言中在定义时可能会出现重命名现象&#xff0c;造成空间冲突&#xff0c;c语言中有命名冲突&#xff1a;1 和库冲突。2 互相之间的冲突&#xff0c;变量命名冲突。所以c中就有了对其改进的关键字namespace&#xff0c;针对重定义&#xff0c;解决空间冲突。 文章目录命…

总结820

学习目标&#xff1a; 4月&#xff08;复习完高数18讲内容&#xff0c;背诵21篇短文&#xff0c;熟词僻义300词基础词&#xff09; 学习内容&#xff1a; 高等数学&#xff1a;巩固所学&#xff0c;1~10讲内容回顾 rule No.1:never lost your knowledge. rule No.2:never f…

C++基础语法(模板)

C的模板是什么&#xff1f;有什么用&#xff1f;如果你想知道问题的答案&#xff0c;那么看这篇博客就对了&#xff0c;在这篇博客中&#xff0c;我们将探讨泛型编程&#xff0c;C模板的具体内容 目录 模板概念 函数模板 显示实例化与隐式实例化 模板不支持声明和定义分离 类模…

104.(cesium篇)cesium卫星轨道模拟

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <html lang="en"> <