JavaScript 系列之:事件

server/2025/3/3 6:23:21/

传播机制 - 事件流

在 DOM 中触发事件(如点击或鼠标移动)时,事件会经过一个或多个元素,形成所谓的“事件流”。DOM 事件流包含三个阶段:捕获阶段、目标阶段和冒泡阶段。

  • 捕获阶段:

    • 事件从 document 开始,沿着 DOM 树向下传播,直到触发事件的目标元素。

    • 只有为捕获阶段注册的事件监听器会被触发。

  • 目标阶段:

    • 事件到达目标元素时,目标元素上的事件监听器会被触发。
  • 冒泡阶段:

    • 事件从目标元素开始,向上沿着 DOM 树传播,直到 document。

    • 只有为冒泡阶段注册的事件监听器会被触发。

注意事项:

  • 使用 addEventListener 注册事件时,第三个参数决定监听器是在捕获阶段还是冒泡阶段触发

    • 默认情况下(第三个参数未设置或为 false),事件监听器在冒泡阶段触发。

    • 如果指定第三个参数为 true,则在捕获阶段触发。

  • 一种类型的事件不会触发不同类型的事件处理器。例如,click 事件不会触发 keydown 事件的处理器。

事件委托

在实际开发中,捕获阶段的应用相对较少,而冒泡阶段的应用则更为广泛。

开发者常利用冒泡阶段来监听多个元素的共同事件,从而减少代码的重复性。

一个典型的应用是事件委托,即将事件监听器绑定到父元素上,从而实现对动态添加子元素的事件监听。

这不仅减少了代码量,还能提高页面性能,降低内存消耗。

事件对象 - event

当事件被触发时,浏览器会创建一个事件对象,并将其作为参数传递给事件处理函数。

这个事件对象包含了与事件相关的所有信息:如事件的类型、触发事件的目标元素、鼠标的位置等。

通过事件对象,我们可以获取这些信息,并在事件处理函数中使用它们。

event 常用属性和方法:

属性/方法描述
type返回事件的名称,如 click、keydown 等。
target返回实际触发事件的元素。
currentTarget返回当前正在处理事件的元素。
timeStamp返回事件创建的日期和时间(以毫秒为单位)。
preventDefault()调用此方法可以阻止事件的默认行为。例如,阻止表单的提交或阻止链接的导航。
stopPropagation()调用此方法可以阻止事件进一步冒泡到 DOM 树中的上层元素。

target 和 currentTarget 的区别:

  • target:

    • target 是指实际触发事件的元素。即使事件通过事件冒泡(或捕获)传播,target 始终是事件最初发生的元素。

    • 比如,如果你点击了一个按钮,而这个按钮被包含在一个 div 元素中,target 就是被点击的按钮,而不是包含它的 div。

  • currentTarget:

    • currentTarget 指的是当前正在处理事件的元素,通常是事件处理器绑定的元素。

    • 如果你给父元素绑定了事件监听器,currentTarget 就是绑定事件的父元素,而不是实际触发事件的子元素。

事件监听器 - addEventListener

事件监听器 是一个函数,当指定事件发生在指定元素上时,该函数会被调用。可以通过 addEventListener() 方法为元素添加事件监听器。

语法:

addEventListener(type, listener, useCapture);

  • type:事件类型

  • listener:回调函数

  • useCapture:一个布尔值,定义事件是在冒泡阶段(默认)还是捕获阶段(true)触发

javascript"> const element = document.getElementById('test');element.addEventListener('click', function(event) {console.log(event)});child.addEventListener('click', function(event) {console.log('target:', event.target); // 会输出触发事件的元素console.log('currentTarget:', event.currentTarget); // 会输出绑定事件监听器的元素});

鼠标事件

事件描述
click当用户点击某个对象时触发
dblclick当用户双击某个对象时触发
mousedown当鼠标按钮被按下时触发
mouseup当鼠标按键被松开时触发
mouseenter当鼠标指针移动到元素上时触发
mouseleave当鼠标指针移出元素时触发
mouseover当鼠标移到某元素之上时触发
mouseout当鼠标从某元素移开时触发
mousemove当鼠标在元素内部移动时触发
contextmenu当用户点击鼠标右键打开上下文菜单时触发

mouseenter 和 mouseover 区别:

  • mouseenter “进入即触发,不冒泡”

    • 仅在鼠标首次进入元素时触发,不考虑鼠标在元素内的移动或进入子元素的情况。

    • 不支持事件冒泡,即当鼠标从子元素移动到父元素时,不会触发父元素的 mouseenter 事件。

  • mouseover “进入和移动都触发,且冒泡”

    • 在鼠标进入元素时触发,且当鼠标在元素内移动或进入其子元素时也会触发。

    • 支持事件冒泡,鼠标在元素及其子元素上的移动都会触发相应的事件,且事件会冒泡到父元素。

键盘事件

事件描述
keydown当某个键盘按键被按下时触发。
keyup当某个键盘按键被松开时触发。
keypress当某个键盘按键被按下并松开时触发(注意:在某些浏览器中,对于某些特殊键 keypress 事件可能不会触发,如修饰键)。

举例:

// 获取输入框元素
const inputElement = document.getElementById('myInput');// 定义当按下回车时执行的函数
function handleEnterPress(event) {if (event.keyCode === 13) {// 在这里编写你要执行的代码console.log('回车键被按下了!');}
}// 为输入框添加键盘事件监听器
inputElement.addEventListener('keydown', handleEnterPress);

表单事件

事件描述
submit当表单提交时触发
change当表单元素的内容改变时触发(如 <input>, <textarea>, <select> 等)
blur当元素失去焦点时触发
focus当元素获取焦点时触发
focusin当元素即将获取焦点时触发
focusout当元素即将失去焦点时触发
input当元素获取用户输入时触发(如实时输入时)
reset当表单重置时触发

举例:

<!DOCTYPE html>  
<html lang="en">  <head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>表单事件示例</title>  </head><body>  <form id="myForm">  <label for="username">用户名:</label>  <input type="text" id="username" name="username" required>  <br>  <label for="password">密码:</label>  <input type="password" id="password" name="password" required>  <br>  <input type="submit" value="提交">  </form>  <script src="script.js"></script>  </body>  
</html>
document.addEventListener('DOMContentLoaded', function() {  // 获取表单元素  var form = document.getElementById('myForm');  // 为表单添加 submit 事件监听器  form.addEventListener('submit', function(event) {  // 阻止表单的默认提交行为,以便我们可以执行自定义操作  event.preventDefault();  // 验证表单输入(这里只是简单示例)  var username = document.getElementById('username').value;  var password = document.getElementById('password').value;  if (username === '' || password === '') {  alert('用户名和密码不能为空!');  return;  }  // 假设验证通过,执行其他操作(例如,发送AJAX请求)  console.log('表单数据:', { username: username, password: password });  // 如果需要提交表单到服务器,可以取消注释下面的代码  // form.submit(); // 但在实际应用中,通常会使用AJAX来异步发送数据  });  
});

窗口和文档事件

事件描述
DOMContentLoaded当 HTML 文档被完全加载和解析后触发,无需等待样式表、图像等加载完成
load在整个页面及其所有依赖资源(如样式表和图片)都加载完成后触发
resize当窗口大小改变时触发
scroll当文档被滚动时触发
beforeunload当即将离开页面(刷新或关闭)时触发
unload当用户退出页面时触发(注意:由于安全和性能原因,此事件在大多数现代浏览器中可能无法正常工作)

DOMContentLoaded 事件在 HTML 文档完全加载和解析后触发,不必等到样式表、图像等其他资源加载完成。因此,DOMContentLoaded 事件会比 load 事件早触发。

DOMContentLoaded 事件也是使用 addEventListener 方法来监听 。

其他事件

事件描述
hashchange当当前 URL 的锚部分(hash)发生修改时触发
abort当图像的加载被中断时触发
error在加载文档或图像时发生错误时触发

HTML 事件属性

属性描述
onload网页加载事件
onclick点击事件
ondblclick双点事件
onmouseover光标移上标签触发
onmouseout光标移走时触发
onmousedown光标按下事件
onmouseup光标弹起事件

鼠标事件 click 和 HTML 事件 onclick 的区别:

  • click 是 JavaScript 中的一个事件类型,是写在 JavaScript 代码中的

    javascript">document.getElementById("myButton").addEventListener("click", function() {alert("Button clicked!");
    });
    
  • onclick 是一个 HTML 事件属性,是写在 HTML 元素标签中的

    javascript"><button id="myButton" onclick="alert('Button clicked!')">Click me</button>
    

注意:

  • 使用 addEventListener 可以给一个元素可以添加多个相同类型的事件处理函数

    <template><button id="test1">测试</button>
    </template><script setup>javascript">
    import { onMounted } from 'vue';
    onMounted(() => {document.getElementById('test1').addEventListener('click', () => {console.log(1);});document.getElementById('test1').addEventListener('click', () => {console.log(2);});
    });
    </script>
    

    点击按钮会同时打印 1 和 2

  • 但是一个元素只能有一个相同类型的 HTML 事件属性,重复会报错 Duplicate attribute

  • onload 属性可以用在 <body>、<img>、<script> 标签,不能用在 <div>、<button> 等标签;同时它还是 window 对象的一个事件属性,用来指定当页面及其所有资源(包括图片、脚本、CSS 等)加载完成后要执行的函数。

    <body onload="javascript language-javascript">console.log('页面加载完成!')"><h1>欢迎访问我的网站!</h1>
    </body><img src="image.jpg" onload="javascript language-javascript">console.log('图片加载完成!')" /><script src="example.js" onload="javascript language-javascript">console.log('脚本加载完成!')"></script><script>javascript">window.onload = function() {alert('页面和所有资源加载完成1!');};// 在 js 中可以写多个 onload 而不会报错,但是后面的会覆盖前面的,并不会都执行window.onload = function() {alert('页面和所有资源加载完成2!');};
    </script>
    

DOMContentLoaded、load、onload 执行顺序

javascript">window.addEventListener('DOMContentLoaded', function () {console.log('DOMContentLoaded 执行完毕');
});window.addEventListener('load', function () {console.log('load 执行完毕');
});window.onload = function () {console.log('onload 执行完毕');
};// DOMContentLoaded 执行完毕
// load 执行完毕
// onload 执行完毕

http://www.ppmy.cn/server/171991.html

相关文章

基于Python+Vue开发的母婴商城管理系统源码+课程作业

项目简介 该项目是基于PythonVue开发的母婴商城管理系统&#xff08;前后端分离&#xff09;&#xff0c;这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Python编程技能&#xff0c;同时锻炼他们的项目设计与开发能力。通过学习基于Python的网上母…

表单验证和正则表达式

表单验证 表单&#xff1a;收集用户信息&#xff0c;并把信息发送给服务器程序进行处理 what 验证数据的格式&#xff0c;将符合标准数据格式要求的数据&#xff0c;发送给后台。 对用户的输入做格式校验&#xff0c;确保能够发送到后台服务器的数据一定是正确的。降低服务器…

《Llama 3.2-Vision:开启多模态AI新时代》:此文为AI自动生成

Llama 3.2-Vision 是什么 在人工智能的快速发展进程中&#xff0c;多模态技术成为了推动行业变革的关键力量。Llama 3.2-Vision 作为 Meta 公司推出的新一代多模态大语言模型&#xff0c;以其卓越的视觉与语言融合能力&#xff0c;为 AI 领域带来了全新的突破。它的出现&#…

openEuler环境下GlusterFS分布式存储集群部署指南

1.环境准备&#xff1a; os&#xff1a;openEuler 22.03 主机名 IP地址 主机用途 Rocky8192.168.121.160客户端 open-Euler1192.168.121.150节点1&#xff0c;提供两块6G硬盘open-Euler4192.168.121.153节点2&#xff0c;提供两块6G硬盘open-Euler5192.168.121.154 …

windows系统备份mysql数据库文件和备份neo4j数据库文件

1.备份mysql数据库文件 mysql -u [用户名] -p [目标数据库名] < [导入文件路径].sql参数说明&#xff1a; [用户名]&#xff1a;连接 MySQL 数据库时使用的用户名。一般默认是root [目标数据库名]&#xff1a;要备份的数据库名称 [导入文件路径]&#xff1a;保存 SQL 文件的…

【沙漠之心:揭秘尘封奇迹的终极之旅】

在地球的边缘,横亘着一片浩瀚无垠的沙漠,它既是生命的绝域,亦是奇迹孕育的秘境。这片广袤的沙漠,以其神秘莫测的面貌,自古以来便吸引着无数探险家、旅行者和梦想家的目光。它既是生命的禁区,让无数生命在这片不毛之地中消逝;同时,它也是奇迹的摇篮,孕育着无数未被发现…

springboot之集成Elasticsearch

目录 二、Elasticsearch 是什么&#xff1f;三、Elasticsearch 安装四、Springboot 集成 Elasticsearch 的方式五、创建项目集成 Elasticsearch 2.创建 Spring Initializr 项目 es &#xff08;3&#xff09;.新建实体类 User&#xff08;4&#xff09;.新建 dao 接口类 UserR…

DeepSeek 助力 Vue3 开发:打造丝滑的弹性布局(Flexbox)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…