js教程(8)

一、事件流

1.概述

        在JavaScript中,事件流描述的是事件在DOM结构中传播和被处理的顺序。事件流分为冒泡阶段和捕获阶段。

        冒泡阶段(Bubbling Phase):事件首先从最内层的元素开始向父级元素传播,一直传播到最外层的元素。在这个阶段,事件是从内向外传播的。

        捕获阶段(Capturing Phase):与冒泡相反,事件从最外层的元素开始传播,一直传播到最内层的元素。在这个阶段,事件是从外向内传播的。

         事件的传播过程:

  1. 捕获阶段:事件从根元素传播到目标元素,依次触发每个元素上绑定的捕获事件处理程序。
  2. 目标阶段:事件到达目标元素,触发目标元素上绑定的事件处理程序。
  3. 冒泡阶段:事件从目标元素开始向上冒泡,依次触发每个元素上绑定的冒泡事件处理程序。

        在实际开发中,事件处理程序一般是绑定在目标元素上,通过事件冒泡机制,可以在目标元素的父元素上捕获到事件,实现事件委托和事件代理等功能。

        简单来说,捕获阶段是从父到子,冒泡阶段是从子到父,而实践开发中都是使用事件冒泡为主。

2.事件捕获

        从DOM的根元素开始去执行对应的事件,事件捕获需要写对应代码才能看到效果,语法如下:

DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制);

说明:

  • addEventListener第第三个参数传入true代表是捕获阶段触发(很少使用);
  • 若传入false代表冒泡阶段触发,默认就是false;
  • 若是用L0事件监听,则只有冒泡阶段,没有捕获。 

3.事件冒泡

        当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称之为事件冒泡,简单理解就是当一个元素触发事件时,会依次向上调用所有的父级元素的同名事件。

举例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>事件冒泡</title>
    <style>
        .father{
            width: 50%;
            height: 300px;
            background-color: yellow;
        }
        .son{
            width: 50%;
            height: 300px;
            background-color: blue;
        }
    </style>
</head>
<body>
    我是爷爷元素
    <div class="father">
        我是父元素
        <div class="son">
            我是子元素
        </div>
    </div>
</body>
<script>
    const father = document.querySelector(".father");
    const son = document.querySelector(".son");
    document.addEventListener('click',()=>{
        alert("爷爷来了");
    });
    father.addEventListener('click',()=>{
        alert("爸爸来了");
    });
    son.addEventListener('click',()=>{
        alert("儿子来了");
    });
</script>
</html>

此时,若点击子元素,则父元素和爷元素的箭头函数也会被触发。

 

 

4.阻止事件冒泡

        因为默认就有冒泡模式的存在,所以很容易导致事件影响到父级元素,若想把事件就限制在当前元素内,就需要阻止事件冒泡。

语法:

事件对象.stopPropagation();

示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>事件冒泡</title>
    <style>
        .father{
            width: 50%;
            height: 300px;
            background-color: yellow;
        }
        .son{
            width: 50%;
            height: 300px;
            background-color: blue;
        }
    </style>
</head>
<body>
    我是爷爷元素
    <div class="father">
        我是父元素
        <div class="son">
            我是子元素
        </div>
    </div>
</body>
<script>
    const father = document.querySelector(".father");
    const son = document.querySelector(".son");
    document.addEventListener('click',()=>{
        alert("爷爷来了");
    });
    father.addEventListener('click',(effervescence)=>{
        alert("爸爸来了");
        effervescence.stopPropagation();
    });
    son.addEventListener('click',(effervescence)=>{
        alert("儿子来了");
        effervescence.stopPropagation();
    });
</script>
</html>

 此方法可以阻断事件流动传播,不光在冒泡阶段有效,在捕获阶段同样有效。

5.阻止事件默认行为

        我们某些情况下需要阻止默认行为的发生,比如阻止链接的跳转,表单域的跳转。

语法:

事件对象.preventDefault();

示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>阻止默认行为</title>
</head>
<body>
    <form action="#">
        <input type="submit" value="提交">
    </form>
</body>
<script>
    const form = document.querySelector('form');
    form.addEventListener("click",(e)=>{
        e.preventDefault();
    })
</script>
</html>

 6.解绑事件

(1)on事件方式

        直接使用null覆盖就可以实现事件的解绑。

语法:

btn.onclick = function(){
    alert("我被点击了");
}
btn.onclick = null;

(2)addEventListener方式

        必须使用removeEventListener(事件类型,事件处理函数[,获取捕获或者冒泡阶段])方法可以解绑事件,注意匿名函数无法被解绑。

function fn(){
    alert("我被点击了");
}
btn.addEventListener("click",fn);
btn.removeEventListener("click",fn);

二、一些注意事项和总结

1.鼠标经过事件

  • mouseover和mouseout会有冒泡效果;
  • mouseenter和mouseleave没有冒泡效果,这里推荐优先使用;

2.两种注册事件的区别

(1)传统on注册(L0)

  • 同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
  • 直接使用null覆盖就可以实现事件的解绑;
  • 都是冒泡阶段执行的

(2)事件监听注册

  • 语法:addEventListener(事件类型,事件处理函数,是否使用捕获);
  • 后面注册事件不会覆盖前面注册的事件(同一个事件);
  • 可以通过第三个参数去确定在冒泡或者捕获阶段执行;
  • 必须使用removeEventLintener(事件类型,事件处理函数,是否使用捕获)解绑函数;
  • 匿名函数无法被解绑。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

树型结构、二叉树、二叉树的创建销毁、二叉树的四种遍历、二叉树层序遍历与队列结合

我要成为嵌入式高手之3月23日数据结构第六天&#xff01;&#xff01; ———————————————————————————— 树形结构 特性&#xff1a; 一对多 概念&#xff1a; 由n个结点组成的有限集 有一个根结点&#xff1b;其他结点只有一个前驱结点&#xff…

图论基础|841.钥匙和房间、463. 岛屿的周长

目录 841.钥匙和房间 思路&#xff1a;本题是一个有向图搜索全路径的问题。 只能用深搜&#xff08;DFS&#xff09;或者广搜&#xff08;BFS&#xff09;来搜。 463. 岛屿的周长 841.钥匙和房间 力扣题目链接 (opens new window) 有 N 个房间&#xff0c;开始时你位于 0…

Windows Server 2016 配置NTP客户端

目录 1. 前提条件1.1 进入服务管理界面1.2 开启Windows Time服务 2. 情况1&#xff1a;可以直接设置NTP时钟2.1 Internet时间设置 3. 情况2&#xff1a;有的版本服务器上没有“Internet时间”3.1 运行gpedit.msc 打开本地策略组3.2 Windows 时间服务3.3 配置Windows NTP客户端3…

2023年天府杯全国大学生数学建模竞赛A题震源属性识别模型构建与震级预测解题全过程文档及程序

2023年天府杯全国大学生数学建模竞赛 A题 震源属性识别模型构建与震级预测 原题再现&#xff1a; 地震是一种较为复杂的地壳运动现象&#xff0c;全世界每年发生的地震灾害事故不计其数。旨在减少地震灾害的地震预警预报技术需要在日常地震监测中有效识别出天然地震事件&…

go面向对象

继承 封装 多态 定义结构体 //定义老师的结构体 type Teacher struct {Name stringAge intSchool string }func main() {var t1 Teacherfmt.Println(t1)t1.Name "tom"t1.Age 20t1.School "school"fmt.Println(t1) } 结构体实例的创建 package ma…

springboot项目中,子模块中无法引入父模块中类

问题&#xff1a; 当前模块kangning_admin中想引入 com.google.code.kaptcha.Producer类&#xff0c;但是当前模块中没有该类 解决办法 1、在pom.xml文件上右键---Maven---Reload project 重新加载pom文件中的依赖 2、 在Idea的右边Maven窗口&#xff0c;在根目录上执行cle…

基于SpringBoot的会员制医疗预约服务管理信息系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea 系统展示 系统功能模块 会员制医疗预约服务管…

02课程发布模块之部署Nginx

部署Nginx 部署网关 通过Nginx访问后台网关&#xff0c;然后由网关再将请求转发到具体的微服务,网关会把请求转发到具体的服务 upstream gatewayserver{server 127.0.0.1:63010 weight10; } # 网站首页对应的虚拟机 server {listen 80;server_name www.51xuecheng.cn…

Java 沉淀-2

一维数组 初始化&#xff1a; 动态初始化&#xff1a;数组声明且为数组元素分配空间与赋值操作分开进行 静态初始化&#xff1a;在定义数组的同时就为数组元素分配空间并赋值 数组元素类型 二维数组 数组中的数组 初始化 注意特殊学法情况&#xff1a;int[]x,y[]: x是一维数…

数据库范式拆分实战

函数依赖 如果给定一个X&#xff0c;能唯一确定一个Y&#xff0c;就称X确定Y&#xff0c;或者说Y依赖于X&#xff0c;例如Y X*X函数。 X -> Y&#xff08;X确定Y&#xff0c;Y依赖于X&#xff09; 部分函数依赖 A可确定C&#xff0c;&#xff08;A&#xff0c;B&#xff09…

[金三银四] 操作系统上下文切换系列

图源&#xff1a; https://zhuanlan.zhihu.com/p/540717796 文章目录 2.11 cpu 的上下文切换2.12 协程的上下文切换2.13 线程的上下文切换2.14 进程的上下文切换2.15 中断上下文切换2.16 什么时候会发生进程的上下文切换2.17 什么时候会发生线程的上下文切换2.18 什么时候会发生…

程序汪保姆教程在linux上部署运行一套SpringBoot内容管理系统

❝ 程序汪已经分享了很多开源项目了&#xff0c;发现一个痛点很多人拿到开源项目了不会部署运行&#xff0c;光看代码很多人看不下去的&#xff08;程序汪也是这样&#xff09;&#xff0c;程序汪建议拿到开源项目了&#xff0c;一定要想办法把项目运行起来跑跑&#xff0c;然后…

树的遍历方式DFS和BFS

DFS(depth first search) 深度优先遍历 从图中一个未访问的顶点V开始&#xff0c;沿着一条路一直走到底&#xff0c;然后从这条路尽头的节点回退到上一个节点&#xff0c;再从另一条路走到底…不断递归重复这个过程&#xff0c;直到所有的顶点都遍历完成。前序遍历&#xff0c…

【Postman】工具使用介绍

一、postman工具介绍 1.什么是postman postman是谷歌开发的一款网页调试和接口测试工具&#xff0c;能够发送任何请求类型的http请求&#xff0c;支持GET/POST/PUT/DELETE等方法。postman简单易用&#xff0c;可以直接填写URL&#xff0c;header&#xff0c;body就可以发送一…

OpenHarmony开发自测试执行框架

OpenHarmony为开发者提供了一套全面的开发自测试框架OHA-developer_test&#xff0c;开发者可根据测试需求开发相关测试用例&#xff0c;开发阶段提前发现缺陷&#xff0c;大幅提高代码质量。 本文从基础环境构建&#xff0c;用例开发&#xff0c;编译以及执行等方面介绍OpenH…

双向链表

目录 单向链表 双向链表 特点 缺点 双向链表的封装 单向链表 只能从头遍历到尾或者从尾遍历到头(一般从头到尾)。也就是链表相连的过程是单向的. 实现的原理是上一个链表中有一个指向下一个的引用 单向链表有一个比较明显的缺点: 我们可以轻松的到达下一个节点,但是回到…

Docker 入门使用说明

Docker 入门使用说明 Docker 安装 Docker 官网&#xff1a;Docker Docker 安装说明&#xff1a;Docker 安装说明 这里由于 Docker 在实时更新&#xff0c;所以每次安装 Docker 用来导入 key 的链接可能会有变化&#xff0c;这里就参考官方的安装方法即可 Docker 常用命令说…

OSCP靶场--Clue

OSCP靶场–Clue 考点(文件读取读取配置中的密码rce认证后利用sudo 提权) 1.nmap扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC -p- 192.168.163.240 --min-rate 2500 Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-14 08:44 EDT Nmap scan report for 192…

网络通信VLAN学习篇

拓扑图 如上图&#xff0c;pc3&#xff0c;pc5同一网络&#xff0c;pc4&#xff0c;pc6同一网络&#xff0c;vlan的划分就是虚拟局域网&#xff0c;局域网的理解就是同一vlan下的设备可以相互通信&#xff0c;不同vlan不可以通信&#xff08;通过三层交换机可以实现通信的&…

缓存穿透、缓存击穿、缓存雪崩及其解决方法

缓存穿透、缓存击穿、缓存雪崩是redis的三大问题。 在介绍这三大问题之前&#xff0c;我们需要先了解Redis作为一个缓存中间件&#xff0c;在项目中是如何工作的。首先看一下在没有缓存中间件的时候的系统数据访问的架构图&#xff1a; 客户端发起一个查询请求的时候&#xff…