当前位置: 首页 > news >正文

JavaScript 中的事件模型

JavaScript 中的事件模型是浏览器如何处理用户交互(如点击、键盘输入、鼠标移动等)或其他事件(如加载完成、定时器等)的机制。理解事件模型有助于我们处理这些事件并响应它们。JavaScript 的事件模型主要包括以下几个部分:

  1. 事件捕获与冒泡(Event Capturing & Event Bubbling)
  2. 事件目标(Event Target)
  3. 事件委托(Event Delegation)
  4. 事件对象(Event Object)
  5. 事件处理程序(Event Handlers)
  6. 事件传播与阻止(Event Propagation & Preventing Default Behavior)

1. 事件流(Event Flow)

事件流是指事件在 DOM(文档对象模型)树中传播的过程。HTML 页面由 DOM 树表示,事件可以沿着 DOM 树的路径传播。事件流由三个阶段组成:

阶段 1:事件捕获阶段(Capturing Phase)

事件从最外层的元素(通常是 windowdocument)向下传播,依次经过各个子元素,直到事件目标元素。

阶段 2:目标阶段(Target Phase)

事件到达事件目标元素,即用户交互的具体元素。

阶段 3:事件冒泡阶段(Bubbling Phase)

事件从目标元素开始向上传播,依次经过其祖先元素,直到最外层的元素。

2. 事件冒泡(Event Bubbling)

事件冒泡是指事件首先在目标元素上触发,然后逐级向上传播到祖先元素,直到 window。这种机制允许我们在父级元素上监听子级元素的事件,因为事件最终会冒泡到父级元素。

示例:
<div id="parent"><button id="child">Click me</button>
</div><script>document.getElementById('parent').addEventListener('click', function() {console.log('Parent clicked');});document.getElementById('child').addEventListener('click', function() {console.log('Child clicked');});
</script>

输出顺序:

Child clicked
Parent clicked

当点击按钮时,事件先在按钮上触发,然后冒泡到 div 父级元素上。

3. 事件捕获(Event Capturing)

与事件冒泡相反,事件捕获是事件从根元素向目标元素传播的过程。默认情况下,事件处理程序只会在冒泡阶段执行,但我们可以指定事件在捕获阶段执行。

示例:
<div id="parent"><button id="child">Click me</button>
</div><script>document.getElementById('parent').addEventListener('click', function() {console.log('Parent clicked');}, true); // 使用 true 表示捕获阶段document.getElementById('child').addEventListener('click', function() {console.log('Child clicked');});
</script>

输出顺序:

Parent clicked
Child clicked

在这个例子中,由于我们在 parent 的事件监听中使用了 trueparent 的点击事件首先在捕获阶段触发。

4. 事件委托(Event Delegation)

事件委托是利用事件冒泡机制,将事件监听器绑定到父级元素,而不是直接绑定在每个子元素上。这有助于减少内存消耗,特别是在动态生成的元素或大量子元素的情况下。

示例:
<ul id="list"><li>Item 1</li><li>Item 2</li><li>Item 3</li>
</ul><script>document.getElementById('list').addEventListener('click', function(event) {if (event.target.tagName === 'LI') {console.log(event.target.innerText + ' clicked');}});
</script>

在这个例子中,我们将点击事件绑定到 ul 元素,而不是每个 li 元素。通过 event.target 判断具体点击的元素是哪一个子节点。

5. 事件对象(Event Object)

当事件触发时,浏览器会创建一个事件对象,并将其作为参数传递给事件处理函数。这个事件对象包含了有关事件的信息,包括事件类型、事件目标、鼠标位置、键盘按键等。

常用的属性和方法:

  • event.type:事件的类型(如 'click''keydown')。
  • event.target:触发事件的元素。
  • event.currentTarget:绑定事件处理程序的元素。
  • event.stopPropagation():阻止事件继续冒泡或捕获。
  • event.preventDefault():阻止事件的默认行为(如阻止链接跳转、表单提交等)。
  • event.clientX / event.clientY:鼠标点击的横纵坐标。
示例:
document.getElementById('child').addEventListener('click', function(event) {console.log('Event type: ', event.type);        // 输出: 'click'console.log('Target: ', event.target);          // 输出: 触发点击的元素console.log('Mouse position: ', event.clientX, event.clientY); // 输出: 鼠标点击位置
});

6. 事件处理程序(Event Handlers)

事件处理程序是用户定义的函数,用于响应某个事件。事件处理程序可以通过三种方式添加到元素上:

  1. HTML 属性方式
<button onclick="handleClick()">Click me</button><script>function handleClick() {console.log('Button clicked');}
</script>
  1. addEventListener 方法(推荐方式):
document.getElementById('button').addEventListener('click', function() {console.log('Button clicked');
});
  1. on 前缀属性(不推荐使用,可能会覆盖其他处理程序):
document.getElementById('button').onclick = function() {console.log('Button clicked');
};

7. 事件传播与阻止

在 JavaScript 中,事件传播过程中可以通过两种方法来控制事件的传播:

1. event.stopPropagation()
  • 阻止事件进一步传播(无论是冒泡还是捕获阶段)。
  • 常用于避免事件冒泡到父级元素中。
document.getElementById('child').addEventListener('click', function(event) {event.stopPropagation(); // 阻止事件冒泡console.log('Child clicked');
});
2. event.preventDefault()
  • 阻止事件的默认行为,如表单提交、链接跳转等。
document.getElementById('link').addEventListener('click', function(event) {event.preventDefault(); // 阻止链接跳转console.log('Link clicked but default action prevented');
});

8. 事件模型的使用场景

  • 表单验证:使用 event.preventDefault() 阻止表单的默认提交行为,执行自定义验证逻辑。
  • 动态 UI 元素:通过事件委托处理动态生成的子元素的事件(如列表项的删除、点击事件)。
  • 交互式用户体验:通过事件冒泡和捕获机制,处理用户点击、悬停、拖动等交互事件。

总结

  • 事件流:事件从最外层元素向内传播(捕获阶段),然后再从内层向外传播(冒泡阶段)。
  • 事件捕获事件冒泡分别控制事件传播的顺序,默认事件处理在冒泡阶段执行。
  • 事件委托是利用事件冒泡,将事件监听器绑定到父级元素,处理子元素的事件。
  • 事件对象提供了有关事件的信息,可以通过 event.target 访问具体的目标元素,使用 stopPropagationpreventDefault 控制事件传播和默认行为。

JavaScript 的事件模型让开发者能够方便地处理各种用户交互,提升网页的动态性和响应能力。

相关文章:

JavaScript 中的事件模型

JavaScript 中的事件模型是浏览器如何处理用户交互&#xff08;如点击、键盘输入、鼠标移动等&#xff09;或其他事件&#xff08;如加载完成、定时器等&#xff09;的机制。理解事件模型有助于我们处理这些事件并响应它们。JavaScript 的事件模型主要包括以下几个部分&#xf…...

理解Java引用数据类型(数组、String)传参机制的一个例子

目录 理解Java引用数据类型&#xff08;数组、String&#xff09;传参机制的一个例子理解样例代码输出 参考资料 理解Java引用数据类型&#xff08;数组、String&#xff09;传参机制的一个例子 理解 引用数据类型传递的是地址。用引用类型A给引用类型B赋值&#xff0c;相当于…...

【计算机组成原理】实验一:运算器输入锁存器数据写实验

目录 实验要求 实验目的 主要集成电路芯片及其逻辑功能 实验原理 实验内容及步骤 实验内容 思考题 实验要求 利用CP226实验箱上的K16&#xff5e;K23二进制拨动开关作为DBUS数据输入端&#xff0c;其它开关作为控制信号的输入端&#xff0c;将通过K16&#xff5e;K23设定…...

LSI SAS 9361-8i和SAS3008 12 gb / s PCIe 3.0 RAID 阵列卡配置

LSI SAS 9361-8i和SAS3008 12 gb / s PCIe 3.0 RAID 阵列卡配置 开机&#xff0c;BIOS自检&#xff0c;可以看到设备硬盘信息&#xff0c;以及提示CtrlR进入Raid卡配置界面。 按CtrlR进入Raid卡配置界面&#xff0c;一般来说使用CtrlR进入Raid卡配置界面的Raid卡配置都通用。 …...

node js版本低导致冲突WARN EBADENGINE package: required: { node: ‘>=18‘ }

重新安装依赖包 1、删除旧的 node_modules 目录和 package-lock.json 文件&#xff1a; rm -rf node_modules rm package-lock.json2、升级node版本 wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bashexport NVM_DIR"$([ -z "${…...

828华为云征文|使用Flexus X实例安装宝塔面板教学

目录 一、Flexus X实例简介 1.1 概述 1.2 产品规格 二、切换操作系统 2.1 Huawei Cloud EulerOS 2.0 标准版 2.2 切换镜像 三、部署宝塔面板 3.1 安装宝塔面板 3.2 放通安全组规则 3.3 登录宝塔面板 四、使用感受 4.1 柔性算力随心配 4.2 一直加速一直快 4.3 越用…...

1.量化第一步,搭建属于自己的金融数据库!

数据是一切量化研究的前提。 做量化没有数据&#xff0c;就相当于做饭时没有食材。 很多时候&#xff0c;我们需要从大量的数据中寻找规律&#xff0c;并从中开发出策略。如果我们每次使用的时候&#xff0c;都从网上去找数据&#xff0c;一方面效率低下&#xff0c;另一方面短…...

git-repo系列教程(6) 在自己服务器上搭建git-repo仓库

为什么要在自己的服务器上搭建git-repo仓库呢? 因为 清华大学开源软件镜像站 有时会更新同步git repo,导致不能使用.可能在局域网不能访问外网,无法下载镜像站上的git-repo仓库完全版. 操作步骤 1.获取git-repo仓库 需要先下载完全的仓库 cd .repo/repo/ #获取镜像站上的…...

微服务——服务保护(Sentinel)(一)

1.雪崩问题 级联失败或雪崩问题指的是在微服务架构中&#xff0c;由于服务间的相互依赖和调用&#xff0c;当一个服务出现故障时&#xff0c;会引起调用它的服务也出现故障&#xff0c;进而引发整个调用链路的多个服务都出现故障&#xff0c;最终导致整个系统崩溃的现象。 产生…...

jenkins声明式流水线语法详解

最基本的语法包含 pipeline&#xff1a;所有有效的声明式流水线必须包含在一个 pipeline 块中stages&#xff1a;包含一系列一个或多个stage指令stage&#xff1a;stage包含在stages中进行&#xff0c;比如某个阶段steps&#xff1a;在阶段中具体得执行操作&#xff0c;一个或…...

mini-lsm通关笔记Week2Overview

Week 2 Overview: Compaction and Persistence 在上周&#xff0c;您已经实现了LSM存储引擎的所有必要结构&#xff0c;并且您的存储引擎已经支持读写接口。在本周中&#xff0c;我们将深入探讨SST文件的磁盘组织&#xff0c;并研究在系统中实现性能和成本效益的最佳方法。我们…...

基于SpringBoot的在线点餐系统【附源码】

​基于SpringBoot的高校社团管理系统&#xff08;源码L文说明文档&#xff09; 4 系统设计 4.1 系统概述 网上点餐系统的结构图4-1所示&#xff1a; 图4-1 系统结构 模块包括主界面&#xff0c;首页、个人中心、用户管理、美食店管理、美食分类管理、美食…...

生成式语言模型底层技术面试

在准备生成式语言模型的底层技术面试时&#xff0c;可以关注以下几个关键领域&#xff1a; 1. 模型架构 Transformer架构&#xff1a;了解自注意力机制、编码器-解码器结构&#xff0c;以及如何处理序列数据。预训练与微调&#xff1a;解释预训练和微调的过程&#xff0c;如何…...

HTML开发指南

目录 一、HTML基础1. HTML简介&#xff08;1&#xff09;标记语言&#xff08;2&#xff09;结构化文档&#xff08;3&#xff09;标签与属性&#xff08;4&#xff09;注释&#xff08;5&#xff09;版本演变 2. HTML文档结构&#xff08;1&#xff09;文档类型声明&#xff0…...

共筑数据安全防线!YashanDB与SPU完成兼容性互认证

近日&#xff0c;深圳计算科学研究院崖山数据库系统YashanDB与深圳市机密计算科技有限公司SPU机密计算协处理器顺利完成兼容性互认证。测试结果表明&#xff0c;双方产品完全兼容&#xff0c;稳定运行&#xff0c;能为用户提供全链路的数据安全管理解决方案&#xff0c;助力央国…...

【FastAPI】使用FastAPI和Redis实现实时通知(SSE)

在当今快速发展的Web应用程序中&#xff0c;实时通知已成为用户体验的重要组成部分。无论是社交媒体更新、消息通知&#xff0c;还是系统状态提醒&#xff0c;实时数据推送可以极大地提升用户互动性。本文将详细介绍如何使用FastAPI和Redis实现Server-Sent Events (SSE) 来推送…...

Keyence_PL_MC_HslCommunication import MelsecMcNet

import tkinter as tk from tkinter import messagebox from datetime import datetime from HslCommunication import MelsecMcNet, OperateResult def 创建_plc_应用程序(): class 应用程序(tk.Tk): def __init__(self): super().__init__() …...

软件架构的演变与趋势(软件架构演变的阶段、综合案例分析:在线电商平台架构演变、开发补充)

随着软件开发技术的不断进步&#xff0c;软件架构从最初的简单结构演变为如今的复杂系统&#xff0c;架构设计不再是简单的代码组合&#xff0c;而是战略性的系统设计&#xff0c;确保系统具备可扩展性、可靠性、安全性和可维护性。 文章目录 1. 软件架构演变的阶段1.1 单体架…...

Shopify独立站运营必知必会:选品与防封技巧

独立站和第三方平台是目前最常见的跨境电商销售模式&#xff0c;相比于第三方平台&#xff0c;独立站的商家可以自己建站&#xff0c;自行决定运营模式和营销手段等策略&#xff0c;尤其是在准入门槛上&#xff0c;难度会更低&#xff0c;这些特点吸引了不少商家选择独立站开店…...

Unity开发绘画板——03.简单的实现绘制功能

从本篇文章开始&#xff0c;将带着大家一起写代码&#xff0c;我不会直接贴出成品代码&#xff0c;而是会把写代码的历程以及遇到的问题、如何解决这些问题都记录在文章里面&#xff0c;当然&#xff0c;同一个问题的解决方案可能会有很多&#xff0c;甚至有更好更高效的方式是…...

R语言的基础知识R语言函数总结

R语言与数据挖掘&#xff1a;公式&#xff1b;数据&#xff1b;方法 R语言特征 对大小写敏感通常&#xff0c;数字&#xff0c;字母&#xff0c;. 和 _都是允许的(在一些国家还包括重音字母)。不过&#xff0c;一个命名必须以 . 或者字母开头&#xff0c;并且如果以 . 开头&…...

龙年国庆专属姓氏头像

关注▲洋洋科创星球▲一起成长&#xff01; 2024年&#xff0c;我们迎来了龙年&#xff0c;龙年国庆姓氏头像&#xff01; 慢慢找&#xff01; 你的和你朋友的都有。 01赵 02 钱 03 孙 04 李 05 周 06 吴 07 郑 08 王 09 冯 010 陈 011 褚 012 卫 013 蒋 014 沈 015 韩 姓氏…...

基于Es和智普AI实现的语义检索

1、什么是语义检索 语义检索是一种利用自然语言处理&#xff08;NLP&#xff09;和人工智能&#xff08;AI&#xff09;技术来理解搜索查询的语义&#xff0c;以提供更准确和相关搜索结果的搜索技术&#xff0c;语义检索是一项突破性的技术&#xff0c;旨在通过深入理解单词和…...

URI和URL的区别

1: 将 URI 转换为 URL import java.net.URI; import java.net.URL;public class UriToUrlExample {public static void main(String[] args) {// 创建一个 URI 对象URI uri = new URI("http://example.com/path/to/resource");// 将 URI 转换为 URLtry {URL url = u…...

Java 入门指南:获取对象的内存地址

文章目录 hashCode()应用重写 hashCode() 方法示例 Symstem . indentityHashCode()应用 注意事项 在 Java 开发中&#xff0c;了解对象的内存管理是十分重要的&#xff0c;尽管 Java 的设计初衷是让开发者更专注于业务逻辑而非底层资源管理。但在某些情况下&#xff0c;了解对象…...

【Linux】项目自动化构建工具-make/Makefile 详解

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…...

嵌入式开发中学习C++的用处?

这个问题一直有同学在问&#xff0c;其实从我的角度是一定是需要学的&#xff0c;最直接的就是你面试大厂的嵌入式岗位或者相关岗位&#xff0c;最后一定会问c&#xff0c;而很多人是不会的&#xff0c;这就是最大的用处&#xff0c;至于从技术角度考量倒是其次&#xff0c;因为…...

基于SAM大模型的遥感影像分割工具,用于创建交互式标注、识别地物的能力,可利用Flask进行封装作为Web后台服务

如有帮助&#xff0c;支持一下&#xff08;GitHub - Lvbta/ImageSegmentationTool-SAM: An interactive annotation case developed based on SAM for remote sensing image annotation, which can generate corresponding segmentation results based on point, multi-point, …...

Selenium入门

Selenium 是一个用于自动化 web 应用程序测试的工具&#xff0c;它支持多种浏览器和编程语言。 下载驱动程序&#xff1a;根据你的浏览器类型和版本&#xff0c;下载相应的 WebDriver。例如&#xff0c;Chrome 浏览器需要 ChromeDriver。 安装 Selenium 库 pip install sele…...

USB 3.1 Micro-A 与 Micro-B 插头,Micro-AB 与 Micro-B 插座,及其引脚定义

连接器配对 下表列出 USB 插座可接受的插头&#xff1a; USB 3.1 Micro-B 连接器 USB 3.1 Micro-B 插头和 USB 3.1 Micro-B 插座连接器是为小型手持设备和其他可能使用小尺寸连接器的应用而定义的。其定义使得 USB 3.1 Micro-B 插座既可以接受 USB 3.1 Micro-B 插头&#xff…...