news 2026/2/22 12:10:56

JavaScript进阶(三):DOM事件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript进阶(三):DOM事件

文章目录

  • 一.事件核心概念
  • 二.常见事件类型(按场景分类)
    • 1.鼠标事件
    • 2.键盘事件
    • 3.表单事件
    • 4.页面 / 窗口事件
    • 5.触摸事件(移动端)
  • 三.事件绑定方式(优先级:推荐 ③ > ② > ①)
    • 1.行内绑定(原生 HTML,不推荐)
    • 2.DOM 属性绑定(简单场景可用)
    • 3.addEventListener(推荐,标准方式)
  • 四.事件对象(event)核心属性 / 方法
  • 五.事件流(捕获 vs 冒泡)
  • 六.事件进阶技巧
    • 1.事件委托(事件代理)
    • 2.防抖(Debounce)
    • 3.节流(Throttle)
    • 4.自定义事件

DOM事件是前端交互的核心,指浏览器或用户触发的各类行为(如 点击、滚动、输入 ),通过「事件绑定 - 事件触发 - 事件处理」的流程实现页面交互逻辑.

一.事件核心概念

概念说明
事件源(target)触发事件的 DOM 元素(如点击的按钮、输入的输入框)
事件类型(type)事件的类别(如clickinputscroll)
事件处理函数(handler)事件触发后执行的函数(也称回调函数)
事件对象(event)事件触发时自动传入处理函数的参数,包含事件的所有信息(如坐标、触发源、按键)
事件流事件在DOM树中的传播过程(捕获阶段 → 目标阶段 → 冒泡阶段)

二.常见事件类型(按场景分类)

1.鼠标事件

最常用的交互事件,适用于点击、悬浮、拖拽等场景:

事件名触发时机常用场景
click鼠标左键单击(按下 + 松开)按钮点击、链接跳转
dblclick鼠标左键双击双击编辑、双击放大
mousedown鼠标按键按下(任意键)拖拽开始、按住操作
mouseup鼠标按键松开(任意键)拖拽结束、释放操作
mousemove鼠标在元素内移动拖拽跟随、鼠标轨迹
mouseover鼠标移入元素(含子元素,会冒泡)悬浮提示(慎用,推荐mouseenter)
mouseenter鼠标移入元素(不含子元素,不冒泡)悬浮菜单、卡片高亮
mouseout鼠标移出元素(含子元素,会冒泡)悬浮提示消失
mouseleave鼠标移出元素(不含子元素,不冒泡)悬浮菜单收起
contextmenu鼠标右键单击自定义右键菜单

2.键盘事件

适用于键盘操作(输入、快捷键):

事件名触发时机关键属性(event)
keydown键盘按键按下(持续按会重复触发)key(按键名,如Enter)、
code(按键编码)、
ctrlKey/shiftKey(修饰键)
keyup键盘按键松开同上
keypress按键按下且产生字符(已废弃,用keydown替代)-

3.表单事件

适用于表单元素交互:

事件名触发时机适用元素
input表单值变化(实时触发)input/textarea/select
change表单值变化且失去焦点(或下拉框选中)同上
focus元素获取焦点(不冒泡)所有表单元素、可聚焦元素(如divtabindex)
blur元素失去焦点(不冒泡)同上
submit表单提交(点击提交按钮 / 按Enter)form元素
reset表单重置form元素

4.页面 / 窗口事件

适用于页面加载、尺寸变化、滚动等:

事件名触发时机注意事项
load页面 / 资源(img/script)加载完成window.onload:页面所有资源加载完成;img.onload:单张图片加载完成
DOMContentLoadedDOM解析完成(无需等待资源加载)load早触发,优先用于初始化逻辑
resize窗口 / 元素尺寸变化高频事件,需防抖
scroll页面 / 元素滚动高频事件,需防抖 / 节流
unload页面卸载(关闭 / 跳转)慎用,执行时机不可靠,推荐beforeunload
beforeunload页面即将卸载可提示用户 “是否离开”

5.触摸事件(移动端)

适用于手机 / 平板的触摸操作:

事件名触发时机关键属性(event)
touchstart手指触摸屏幕touches(所有触摸点)、
targetTouches(当前元素触摸点)
touchmove手指在屏幕上滑动同上,可获取滑动坐标
touchend手指离开屏幕同上
touchcancel触摸被中断(如弹窗、电话)-

三.事件绑定方式(优先级:推荐 ③ > ② > ①)

1.行内绑定(原生 HTML,不推荐)

直接写在 HTML 标签中,耦合度高,不利于维护:

<buttononclick="handleClick()">点击</button><script>functionhandleClick(){alert('点击了按钮');}</script>

⚠️ 缺点:无法绑定多个同类型事件、易引发 XSS、代码分离性差.

2.DOM 属性绑定(简单场景可用)

通过元素属性赋值绑定,只能绑定一个处理函数:

constbtn=document.querySelector('button');// 绑定btn.onclick=function(e){console.log('点击事件',e.target);// e:事件对象};// 解绑btn.onclick=null;

⚠️ 缺点:覆盖原有事件(重新赋值会替换之前的处理函数).

3.addEventListener(推荐,标准方式)

W3C 标准,支持绑定多个处理函数,可控制事件流阶段:

constbtn=document.querySelector('button');// 绑定:参数(事件类型,处理函数,是否捕获/配置项)consthandler=function(e){console.log('点击事件',e);};btn.addEventListener('click',handler);// 绑定多个同类型事件(依次执行)btn.addEventListener('click',()=>{console.log('第二个点击处理函数');});// 解绑:必须传绑定的同一个函数(匿名函数无法解绑)btn.removeEventListener('click',handler);// 配置项(第三个参数可传对象,替代布尔值)btn.addEventListener('scroll',handleScroll,{capture:false,// 否在捕获阶段触发(默认 false,冒泡阶段)once:true,// 事件仅触发一次(自动解绑)passive:true// 禁止阻止默认行为(优化移动端滚动性能)});

✅ 优点:支持多函数绑定、精准解绑、控制事件流、丰富配置项.

四.事件对象(event)核心属性 / 方法

事件处理函数的第一个参数是事件对象,包含事件的所有关键信息:

属性 / 方法作用示例
target事件实际触发的元素(事件源)e.target(冒泡时不会变)
currentTarget绑定事件的元素(this等价)e.currentTarget(冒泡时指向当前处理的元素)
type事件类型(如clickinput)e.type // "click"
clientX/clientY鼠标相对于视口的坐标(不含滚动)鼠标点击位置:e.clientX + 'px'
pageX/pageY鼠标相对于文档的坐标(含滚动)-
key键盘事件的按键名(如Entera)if (e.key === 'Enter') { 提交表单 }
ctrlKey/shiftKey/altKey是否按下修饰键(布尔值)if (e.ctrlKey && e.key === 's') { 保存 }
preventDefault()阻止事件默认行为阻止链接跳转:e.preventDefault()
stopPropagation()阻止事件冒泡 / 捕获阻止父元素触发同类型事件
stopImmediatePropagation()阻止事件传播 + 同元素后续处理函数绑定多个click函数时,后续函数不执行
bubbles事件是否可冒泡(布尔值)e.bubbles // true(如click可冒泡,focus不可)

五.事件流(捕获 vs 冒泡)

事件触发后,会在DOM树中经历三个阶段(W3C 标准):

  1. 捕获阶段:从window→ 文档 → 父元素 → 目标元素(从上到下);
  2. 目标阶段:事件到达实际触发的元素;
  3. 冒泡阶段:从目标元素 → 父元素 → 文档 →window(从下到上).

核心示例(冒泡 vs 捕获)

<divclass="parent"style="padding:20px;background:#eee;"><buttonclass="child">点击</button></div><script>constparent=document.querySelector('.parent');constchild=document.querySelector('.child');// 冒泡阶段触发(默认)parent.addEventListener('click',()=>console.log('父元素-冒泡'));child.addEventListener('click',()=>console.log('子元素-冒泡'));// 捕获阶段触发(第三个参数为true)parent.addEventListener('click',()=>console.log('父元素-捕获'),true);child.addEventListener('click',()=>console.log('子元素-捕获'),true);// 点击按钮,执行顺序:// 父元素-捕获 → 子元素-冒泡 → 子元素-捕获 → 父元素-冒泡// (目标阶段不分捕获/冒泡,按绑定顺序执行)</script>

六.事件进阶技巧

1.事件委托(事件代理)

利用事件冒泡,将子元素的事件绑定到父元素,减少事件绑定数量,优化性能(尤其适用于动态生成的元素):

<ulid="list"><li>项1</li><li>项2</li><!-- 动态添加的li也能触发事件 --></ul><script>constlist=document.getElementById('list');// 委托父元素绑定事件list.addEventListener('click',(e)=>{// 过滤目标元素(仅处理li)if(e.target.tagName==='LI'){console.log('点击了li:',e.target.textContent);}});// 动态添加li,无需重新绑定事件constnewLi=document.createElement('li');newLi.textContent='项3';list.appendChild(newLi);</script>

✅ 优点:减少事件绑定、支持动态元素、降低内存占用.

2.防抖(Debounce)

解决高频事件(如resizescrollinput)频繁触发的问题,仅在事件停止触发后执行一次:

运行;// 防抖函数functiondebounce(fn,delay=300){lettimer=null;returnfunction(...args){clearTimeout(timer);timer=setTimeout(()=>{fn.apply(this,args);},delay);};}// 使用:输入框实时搜索constinput=document.querySelector('input');input.addEventListener('input',debounce(function(e){console.log('搜索:',e.target.value);// 停止输入 300ms 后执行},300));

3.节流(Throttle)

限制高频事件的执行频率,每隔指定时间仅执行一次:

运行;// 节流函数functionthrottle(fn,interval=500){letlastTime=0;returnfunction(...args){constnow=Date.now();if(now-lastTime>=interval){fn.apply(this,args);lastTime=now;}};}// 使用:滚动加载window.addEventListener('scroll',throttle(function(){console.log('滚动中...');// 每 500ms 执行一次},500));

4.自定义事件

手动创建 / 触发事件,适用于组件通信、自定义交互:

// 1. 创建自定义事件constmyEvent=newCustomEvent('custom-click',{detail:{id:123},// 自定义数据bubbles:true,// 允许冒泡cancelable:true// 允许阻止默认行为});// 2. 绑定自定义事件constbtn=document.querySelector('button');btn.addEventListener('custom-click',(e)=>{console.log('自定义事件触发:',e.detail.id);// 输出 123});// 3. 手动触发事件btn.dispatchEvent(myEvent);
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/22 8:58:53

终极Mac观影神器:打造你的私人美剧影院

终极Mac观影神器&#xff1a;打造你的私人美剧影院 【免费下载链接】iMeiJu_Mac 爱美剧Mac客户端 项目地址: https://gitcode.com/gh_mirrors/im/iMeiJu_Mac 还在为找美剧资源而烦恼吗&#xff1f;在各大视频平台间频繁切换&#xff0c;只为找到心仪的那一部&#xff1f…

作者头像 李华
网站建设 2026/2/19 15:25:27

Linux下通过命令行实现防火墙操作

在Linux系统上管理防火墙&#xff0c;ufw (Uncomplicated Firewall) 是一个非常流行且易于使用的工具&#xff0c;它是 iptables 的一个前端。 &#x1f527; UFW的安装 ufw 通常预装在基于Debian的系统&#xff08;如Ubuntu&#xff09;上。如果你的系统没有&#xff0c;可以使…

作者头像 李华
网站建设 2026/2/16 20:16:36

测试数据管理的自动化工具

被忽视的质量基石 在敏捷开发与持续交付成为主流的今天&#xff0c;测试数据管理&#xff08;TDM&#xff09;仍存在明显滞后性。据行业调研显示&#xff0c;超过67%的软件缺陷源于测试数据问题——数据污染、覆盖不全、环境差异等痛点直接拖累交付周期。本文通过解构自动化工…

作者头像 李华
网站建设 2026/2/21 16:05:40

智能测试数据脱敏技术:保障数据安全与测试效率的工程实践

测试数据管理的困境与破局 在敏捷开发与DevOps普及的今天&#xff0c;软件测试活动日趋频繁。传统的测试数据准备方式——无论是直接使用生产数据的“裸奔”行为&#xff0c;还是耗费大量人力手动编写模拟数据的“作坊”模式——都已无法满足现代软件工程对效率、安全与质量的…

作者头像 李华
网站建设 2026/2/20 15:56:09

MTK设备bootrom保护绕过技术详解:专业级安全解锁方案

MTK设备bootrom保护绕过技术详解&#xff1a;专业级安全解锁方案 【免费下载链接】bypass_utility 项目地址: https://gitcode.com/gh_mirrors/by/bypass_utility MTK芯片设备的安全保护机制一直是手机刷机和系统定制的重要障碍。本工具通过技术手段实现对bootrom保护的…

作者头像 李华