「JavaScript基础」一文彻底搞懂JS的事件流以及事件模型

news2024/11/24 10:36:14

目录

  • 事件
    • 事件机制
      • 一、事件绑定
      • 二、事件监听
      • 三、事件委托
  • 事件流
    • 事件流模型
    • DOM事件处理
      • DOM0
      • DOM2
      • IE 事件处理程序
  • 常见的事件


在JavaScript中,事件流和事件模型是处理用户交互的关键概念。深入理解这些概念将使你能够更好地处理和响应用户的动作。本文将详细介绍JavaScript的事件流和事件模型。

事件

在了解什么是事件流之前,我们先了解一下什么是事件

事件是文档或浏览器窗口中发生的一些特定的交互瞬间

HTML事件就是发生在HTML元素上的事情
当在HTML中使用javaScript时,javaScript能够应对这些事件
比如鼠标点击、键盘按键、页面加载、表单提交…

事件机制

事件绑定、事件监听、事件委托(事件代理)

一、事件绑定

事件绑定是指将事件处理函数附加到特定的DOM元素上。

在JavaScript中,有以下几种绑定事件的方法(以click为例):

  • 在DOM元素中直接绑定
    可以直接在DOM元素上绑定某个事件

    <div onclick="hello()">click me</div>
    <script>
    function hello(){
    	alert("hello world!");
    }
    </script>
    
  • 在JavaScript代码中绑定
    在JavaScript代码中绑定事件可以使JavaScript代码与HTML标签分离,文档结构清晰,便于管理和开发。

    <div id="btn">click me</div>
    <script>
    document.getElementById("btn").onclick = hello
    function hello(){
    	alert("hello world!");
    }
    </script>
    
  • 绑定事件监听函数
    使用 addEventListener()attachEvent()【IE标准】 来绑定事件监听函数。

    👇下面请看事件监听

二、事件监听

事件监听的优点

  1. 可以绑定多个事件
    btn1.addEventListener("click",hello1)
    btn2.addEventListener("click",hello2)
  2. 可以解除相应的绑定
    addEventListener() => removeEventListener()
    attachEvent() => detachEvent()

element.addEventListener(event, function, useCapture)

  • event : (必需)事件名,支持所有 DOM事件

  • function:(必需)指定要事件触发时执行的函数

  • useCapture:(可选)指定事件是否在捕获或冒泡阶段执行。true => 在事件捕获阶段调用;false[默认] => 在事件冒泡阶段调用

  • 注意:IE8以下不支持

  • 示例👇

    <div id="btn">click me</div>
    <script>
    document.getElementById("btn").addEventListener("click", hello);
    function hello(){
    	alert("hello world!");
    }
    </script>
    

element.attachEvent(event, function) 【IE标准】

  • event:(必需)事件类型。需加on,例如:onclick
  • function:(必需)指定要事件触发时执行的函数。
  • 示例👇
    <div id="btn1">click me</div>
    <script>
    document.getElementById("btn1").attachEvent("onclick",hello);
    function hello(){
    	alert("hello world!");
    }
    </script>
    

三、事件委托

事件监听的优点

  1. 提高JavaScript性能。事件委托可以显著的提高事件的处理速度,减少内存的占用。 【DEMO】
  2. 动态的添加DOM元素,不需要因为元素的改动而修改事件绑定。

事件委托就是利用冒泡的原理,把事件加到父元素或祖先元素上,触发执行效果。

示例👇

<div id="btn">click me</div>
<script>
   const btn = document.getElementById("btn");
   document.onclick = function(event){
       event = event || window.event;
       var target = event.target || event.srcElement;
       if(target == btn){
           hello()
       }
   }

function hello(){
	alert("hello world!");
}

事件流

事件流 是从页面中接收事件的顺序。

事件流模型

DOM事件流规范规定事件流分为 3 个阶段:

  1. 事件捕获阶段:事件从上往下查找对应元素,直到捕获到事件
  2. 处于目标阶段:目标元素后执行事件对应的处理函数
  3. 事件冒泡阶段:事件从目标元素开始冒泡

在这里插入图片描述
Tips: 在 DOM 事件流中,实际的目标(元素)在捕获阶段不会收到事件。这是因为捕获阶段从document到元素就结束了。下一阶段,即会在元素上触发事件的"处于目标"阶段,通常在事件处理时被认为是冒泡阶段的一部分。然后冒泡阶段开始,事件反向传播至文档。


DOM事件处理

DOM节点中有了事件,那我们就需要对事件进行处理。

DOM0

DOM0级事件具有极好的跨浏览器优势,会以最快的速度绑定。

  1. 内联模型(行内绑定):将函数名直接作为html标签中属性的属性值

    <div onclick="handleClick" >Click Me</div>
    <script>
    function handleClick(){
        alert("hello world!");
    }
    </script>
    
  2. 脚本模型(动态绑定),通过在JS中选中某个节点,然后给节点添加onclick属性。

    <div id="btn">Click Me</div>
    <script>
    const btn = document.getElementById("btn");
    btn.onclick = handleClick()
    function handleClick(){
        alert("hello world!");
    }
    </script>
    

Tips1: 使用 on 开头的事件,同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。

<div id="btn">Click Me</div>
<script>
const btn = document.getElementById("btn");
btn.onclick = handleClick()
btn.onclick = handleClick2()
function handleClick(){
    alert("hello world!");
}
function handleClick2(){
    alert("hello world222!");
}
// 输出 hello world222!
</script>

Tips2: DOM0级只支持冒泡阶段

<div id="btn1" style="height: 200px;width: 200px;background: red;">
    btn1
    <div id="btn2" style="height: 150px;width: 150px;background: green;">
        btn2
        <div id="btn3" style="height: 100px;width: 100px;background: blue;">
            btn3
        </div>
    </div>
</div>
<script>
    const btn1 = document.getElementById("btn1");
    const btn2 = document.getElementById("btn2");
    const btn3 = document.getElementById("btn3");
    btn1.onclick=function(){
        console.log(1)
    }
    btn2.onclick=function(){
        console.log(2)
    }
    btn3.onclick=function(){
        console.log(3)
    }
</script>

👇 运行效果
在这里插入图片描述

👇 当点击 btn3 时:
在这里插入图片描述

👇 当点击 btn1 时:
在这里插入图片描述
👉 可以发现:最先触发的是最底层 btn1的事件,最后才是顶层 btn3 的事件,因此很明显是事件冒泡。SO… DOM0级只支持冒泡阶段.


DOM2

定义了两个方法:

  • addEventListener() => 添加事件侦听器
  • removeEventListener() => 移除事件侦听器
  • 具体使用请上滑至 【事件监听】

大多数情况下,事件处理程序会被添加到事件流的冒泡阶段,主要原因是跨浏览器兼容性好。
把事件处理程序注册到捕获阶段通常用于在事件到达其指定目标之前拦截事件。如果不需要拦截,则不要使用事件捕获。

🫠 回头看:
在这里插入图片描述

<div id="btn1" style="height: 200px;width: 200px;background: red;">
    btn1
    <div id="btn2" style="height: 150px;width: 150px;background: green;">
        btn2
        <div id="btn3" style="height: 100px;width: 100px;background: blue;">
            btn3
        </div>
    </div>
</div>
<script>
    const btn1 = document.getElementById("btn1");
    const btn2 = document.getElementById("btn2");
    const btn3 = document.getElementById("btn3");
    btn1.addEventListener('click',function (){
		console.log(1)
	},true)
	btn2.addEventListener('click',function (){
		console.log(2)
	},true)
	btn3.addEventListener('click',function (){
		console.log(3)
	},true)
</script>

👇 当点击 btn3 时:【DOM2中的顺序和DOM0中的顺序反过来了,最外层的btn最先触发,因为 addEventListener 最后一个参数是true,捕获阶段进行处理~】
在这里插入图片描述


IE 事件处理程序

IE 实现了与 DOM2 类似的方法

  • attachEvent() => 附加事件
  • detachEvent() => 剥离事件
  • 具体使用请上滑至 【事件监听】
const btn = document.getElementById("btn");
btn.attachEvent("onclick", function() {
  console.log("hello world!");
});

需要注意以下几点:

  • 使用 attachEvent() 时,事件处理程序是在全局作用域中运行的,因此 this 等于 window。这个差异对编写跨浏览器代码是非常重要的。
  • 使用 attachEvent() 方法也可以给一个元素添加多个事件处理程序。事件处理程序会以添加它们的顺序反向触发。
  • 使用 attachEvent() 添加的事件处理程序将使用 detachEvent() 来移除, 只要提供相同的参数。匿名函数也无法移除。

常见的事件

HTML 事件参考手册

未完待续…

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

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

相关文章

冷链温湿度监控解决方案,实时监测,助力运输安全

为了确保药品、生鲜等在冷链运输过程中的安全监管,需要对冷链、仓库等环节的温湿度信息进行实时自动检测和记录&#xff0c;有效防范储运过程中可能影响产品质量安全的各类风险&#xff0c;确保储存和运输过程的产品质量。 冷链温湿度监控系统解决方案&#xff0c;利用智能温湿…

leetcode—— 腐烂的橘子

腐烂的橘子 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回 直到…

每日一道算法题 15(2023-12-28)TLV解析Ⅰ

package com.tarena.test.B20; import java.util.ArrayList; import java.util.Scanner; import java.util.StringJoiner; /** * TLV解析Ⅰ * author Administrator * 输入&#xff1a; * 第一行 31 * 第二层 32 01 00 AE 90 02 00 21 02 30 03 00 AB 32 31 31 0…

UI自动化测试框架搭建 —— yaml文件管理定位元素

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

万界星空科技mes系统可以为企业带来什么好处

随着信息技术的不断发展&#xff0c;MES生产制造系统的作用不断凸显。万界星空科技MES生产制造可以为企业带来四个方面的好处&#xff1a;提升生产效率、降低生产成本、优化生产过程、提高生产质量。本文将从这四个方面分别进行详细阐述&#xff0c;旨在通过对MES生产制造系统的…

【优先级队列 之 堆的实现】

文章目录 前言优先级队列 PriorityQueue优先队列的模拟实现 堆堆的储存方式堆的创建建堆的时间复杂度堆的插入与删除 总结 前言 优先级队列 PriorityQueue 概念&#xff1a;对列是先进先出的的数据结构&#xff0c;但有些情况&#xff0c;数据可能带有优先级&#xff0c;一般出…

C++11新特性:快速初始化成员变量

在C98中&#xff0c;类成员变量的就地声明通常需要在构造函数中进行初始化。 class MyClass { public:// C98 中的类成员变量声明int myVariable;// 构造函数中初始化MyClass() {myVariable 0;} };并且&#xff0c;C98对类中就地声明要求非常高&#xff0c;如果不是整型或者枚…

java使用easyexcel读取excel内容

java 代码读取excel内容。 使用阿里巴巴easyexcel读取excel内容。 ##excel内容 ##依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.5</version></dependency> ##实体类T…

Adobe Media Encoder 2023下载安装教程,ME 2023安装教程,附安装包和工具,无套路,轻松搞的安装

前言 Adobe Media Encoder是一个视频和音频编码应用程序&#xff0c;可让针对不同应用程序和观众&#xff0c;以各种分发格式对音频和视频文件进行编码。包括专门设计的预设设置&#xff0c;以便导出与特定交付媒体兼容的文件&#xff0c;可以按适合多种设备的格式导出视频&am…

Mybatis集成MySQL使用游标查询处理大批量数据

背景 基于数据的时间范围查询&#xff0c;给符合条件的用户推送积分即将到期的提醒。 初期用户量小使用最普通简单的分页查询扫描数据处理数据没问题。随着用户量的上升表数据已经上千万&#xff0c;每天扫描处理的数量也超百万&#xff0c;limit分页出现了慢sql&#xff0c;…

【EISCOPUS双检索】2024电子、通信与智能科学国际会议(ECIS 2024)征稿通知!

2024年5月24日-27日 中国|长沙 会议重要日期 一轮截稿时间&#xff1a;2024年3月10日 录用通知时间&#xff1a;投稿后7-15天 注册截止时间&#xff1a;2024年5月10日 一、大会背景 随着互联网的不断创新&#xff0c;电子、通信和智能科学已经广泛应用于各个领域。为了为…

HarmonyOS鸿蒙学习基础篇 - 运行第一个程序 Hello World

下载与安装DevEco Studio 古话说得好&#xff0c;“磨刀不误砍柴工”&#xff0c;对于HarmonyOS应用开发&#xff0c;我们首先得确保工具齐全。这就好比要进行HarmonyOS应用开发&#xff0c;我们需要确保已经安装了DevEco Studio&#xff0c;这是HarmonyOS的一站式集成开发环境…

HarmonyOS关于deps、external_deps的使用

在添加一个模块的时候&#xff0c;需要在BUILD.gn中声明它的依赖&#xff0c;为了便于后续处理部件间依赖关系&#xff0c;我们将依赖分为两种——部件内依赖deps和部件间依赖external_deps。 依赖分类 如上图所示&#xff0c;主要分为部件内依赖&#xff08;图左&#xff09;…

一文(10图)了解Cornerstone3D核心概念(万字总结附导图)

Cornerstone3D介绍 Cornerstone3D是一个专门为处理三维医学影像而设计的JavaScript库。 它是Cornerstone项目的一部分&#xff0c;旨在为医学影像社区提供高性能、可扩展且易于使用的开源Web工具&#xff0c;专注于提供交互式的3D医学图像浏览体验&#xff0c;适用于多种医学…

学习Opencv(蝴蝶书/C++)——4.图形和大型数组类型(下)

文章目录 4.5 通过块访问数组(多行多列等范围访问)4.6 矩阵支持的代数运算(运算符重载)4.7 饱和转换4.8 cv::Mat的其他成员函数7. cv::SparsesMat表示N维稀疏数组7.1 基本介绍7.2 引用或者值访问7.2.1 cv::SparsesMat::ptr()7.2.2 cv::SparsesMat::ref()7.2.3 cv::SparsesM…

人民银行成功实现数字人民币与传统支付的互通

西米支付网&#xff08;45ri.com&#xff09;中国人民银行数字货币研究所10月12日在人民银行网站刊发了题为《扎实开展数字人民币研发试点工作》的文章&#xff0c;截至2022年8月31日&#xff0c;已有15个省市的试点地区共计完成了3.6亿笔的交易&#xff0c;交易金额达到了1000…

大小鼠行为刺激-ZL-034B大小鼠跳台仪/多通道跳台记录仪

小鼠跳台实验是一种常用的学习记忆实验方法&#xff0c;它基于条件反射原理&#xff0c;通过观察小鼠在电栅和平台之间跳跃的行为&#xff0c;来研究药物对学习和记忆过程的影响。它适用于各种增智健脑、提高记忆、抗衰老药物和保健品筛选、开发研制。它是初筛药物的理想工具&a…

ubuntu 20.04 aarch64 平台交叉编译 libffi 库

前言 由于打算交叉编译 python&#xff0c;但是依赖 libffi 库&#xff0c;也就是 libffi 库也需要交叉编译 环境&#xff1a; ubuntu 20.04 交叉编译工具链&#xff1a;这里使用 musl libc 的 gcc 交叉编译工具链&#xff0c;aarch64-linux-musleabi-gcc&#xff0c;gcc 版本…

【心得】java反序列化漏洞利用启蒙个人笔记

目录 前置基础概念 java的反序列化利用概念baby题 例题1 例题2 java反序列化启蒙小结&#xff1a; URLDNS链 一句话总结&#xff1a; 简单分析&#xff1a; 利用点&#xff1a; 示例&#xff1a; 前置基础概念 序列化 类实例->字节流 反序列化 字节流->类实…

大模型+自动驾驶

论文&#xff1a;https://arxiv.org/pdf/2401.08045.pdf 大型基础模型的兴起&#xff0c;它们基于广泛的数据集进行训练&#xff0c;正在彻底改变人工智能领域的面貌。例如SAM、DALL-E2和GPT-4这样的模型通过提取复杂的模式&#xff0c;并在不同任务中有效地执行&#xff0c;从…