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

JavaScript加强篇——第三章 事件大全(完整版)

目录

一、事件监听

二、事件监听三要素

三、事件监听版本

四、事件类型

五、事件对象

六、环境对象 (this)

七、回调函数

八、事件流

九、事件捕获

十、事件冒泡

十一、阻止事件冒泡

十二、解绑事件

十三、两种注册事件的区别

十四、鼠标经过事件的区别

十五、事件委托

十六、事件委托

十七、页面加载事件

十八、页面滚动事件

十九、页面尺寸事件

二十、元素尺寸与位置

二十一、滚动位置属性对比


此章节主要讲解:事件监听、事件监听三要素、事件监听版本、事件类型、事件对象、环境对象 (this)、回调函数、事件流、事件捕获、事件冒泡、阻止事件口泡、解绑事件、两种注册事件的区别、鼠标经过事件的区别、事件委托、事件委托、页面加裁事件、页面滚动事件、页面尺寸事件、元素尺寸与位置、滚动位置属性对比。

一、事件监听

核心概念

  • 事件:程序运行时发生的动作或事情(如用户点击按钮)

  • 事件监听:让程序检测事件是否发生,触发时立即调用响应函数

代码示例

const btn = document.querySelector('button');
btn.addEventListener('click', function() {alert('按钮被点击了!');
});

⚠️ 注意事项

  1. 事件类型必须加引号:'click' ✅ 正确 vs click ❌ 错误

  2. 每次触发事件都会执行一次回调函数


二、事件监听三要素

三要素组成

  1. 事件源:被触发的DOM元素

  2. 事件类型:触发方式(click/mouseover等)

  3. 事件处理函数:触发后执行的逻辑

关系图解


三、事件监听版本

两种注册方式

版本语法特点
DOM L0元素.onclick = function绑定会被覆盖
DOM L2addEventListener()可绑定多个事件处理函数

❗ 使用原则

始终使用 addEventListener,避免使用 on事件 方式


四、事件类型

常用事件类型

类别事件类型触发条件
鼠标事件click鼠标点击
mouseenter鼠标进入元素区域
mouseleave鼠标离开元素区域
焦点事件focus元素获得焦点
blur元素失去焦点
键盘事件keydown键盘按键按下
keyup键盘按键释放
文本事件input输入框内容变化

五、事件对象

核心概念

  • 事件对象:事件触发时自动创建,包含事件相关数据

  • 获取方式:回调函数的第一个参数(通常命名为 e

常用属性

属性说明
e.type事件类型(如 'click')
e.clientX/Y光标相对于浏览器窗口的位置
e.offsetX/Y光标相对于当前元素的位置
e.key按下的键盘键值(推荐使用)

⚠️ 注意事项

键盘事件中优先使用 e.key 而不是已废弃的 keyCode


六、环境对象 (this)

核心概念

  • this:函数内部特殊变量,代表当前运行环境

  • 判断规则:谁调用函数,this 就指向谁

示例对比

// 普通函数:this指向调用者
btn.addEventListener('click', function() {console.log(this); // 指向btn元素
});// 箭头函数:this指向定义时的环境
btn.addEventListener('click', () => {console.log(this); // 指向window(通常不是期望结果)
});

七、回调函数

核心概念

  • 回调函数:作为参数传递给另一个函数的函数

  • 常见场景:事件处理、定时器、异步操作

正确用法

// 命名函数(可解绑)
function handleClick() {console.log('点击处理');
}
btn.addEventListener('click', handleClick);// 匿名函数(无法解绑)
btn.addEventListener('click', function() {console.log('匿名回调');
});

⚠️ 易错点

传递函数时使用函数名不加括号
✅ setInterval(callbackFn)
❌ setInterval(callbackFn())(会立即执行)


八、事件流

核心概念

  • 事件流:事件完整执行过程中的流动路径

  • 两个阶段

    1. 捕获阶段:从父元素到子元素(从外到内)

    2. 冒泡阶段:从子元素到父元素(从内到外)

❗ 重要原则

实际开发中主要使用冒泡阶段(默认行为)


九、事件捕获

启用方式

元素.addEventListener(事件类型, 处理函数, true);
// 第三个参数为true表示捕获阶段触发

特点

  1. 从DOM根元素开始执行(从外到里)

  2. 需要显式设置才能观察到效果

  3. DOM L0 不支持捕获(只有冒泡)


十、事件冒泡

核心概念

  • 事件冒泡:事件触发后,会依次向上调用所有父元素的同名事件

  • 默认存在:所有事件监听默认在冒泡阶段触发

示例


<div class="爷爷">爷爷<div class="爸爸">爸爸<div class="儿子">儿子</div></div>
</div><script>
document.querySelector('.爷爷').addEventListener('click', () => alert('爷爷'));
document.querySelector('.爸爸').addEventListener('click', () => alert('爸爸'));
document.querySelector('.儿子').addEventListener('click', () => alert('儿子'));
// 点击"儿子"会依次触发:儿子 → 爸爸 → 爷爷
</script>

十一、阻止事件冒泡

使用场景

需要将事件限制在当前元素内,不影响父元素

实现方法

元素.addEventListener('click', function(e) {e.stopPropagation(); // 阻止事件继续传播// 其他逻辑...
});

⚠️ 注意

此方法在捕获和冒泡阶段都有效


十二、解绑事件

两种解绑方式

1. DOM L0 方式

btn.onclick = function() { /* 逻辑 */ };
// 解绑
btn.onclick = null;

2. DOM L2 方式

function handleClick() { /* 逻辑 */ }// 绑定
btn.addEventListener('click', handleClick);
// 解绑
btn.removeEventListener('click', handleClick);

❗ 关键区别

匿名函数无法被解绑,始终使用命名函数以便解绑


十三、两种注册事件的区别

特性DOM L0 (on事件)DOM L2 (addEventListener)
覆盖问题后注册会覆盖前注册可注册多个处理函数
解绑方式元素.on事件 = nullremoveEventListener
阶段控制仅冒泡阶段可通过参数控制捕获/冒泡阶段
匿名函数可解绑匿名函数无法解绑

十四、鼠标经过事件的区别

事件类型冒泡效果推荐场景
mouseover不推荐
mouseout不推荐
mouseenter✅ 推荐使用
mouseleave✅ 推荐使用

十五、事件委托

解决痛点

当需要给多个相似元素添加事件时,避免循环绑定

实现原理

<ul id="list"><li>选项1</li><li>选项2</li><li>选项3</li>
</ul><script>
document.getElementById('list').addEventListener('click', function(e) {if(e.target.tagName === 'LI') {console.log('点击了:', e.target.textContent);}
});
</script>

核心优势

  1. 性能优化:只需绑定一个事件监听器

  2. 动态元素:自动处理新增的子元素

  3. 内存节省:减少事件监听器数量


✅ 事件系统核心要点总结

图表

代码

黄金实践原则:

  1. 始终使用 addEventListener(DOM L2)

  2. 事件处理函数使用命名函数以便解绑

  3. 鼠标事件使用 mouseenter/mouseleave

  4. 批量元素处理使用事件委托

  5. 需要阻止冒泡时使用 e.stopPropagation()

十六、事件委托

核心概念

利用事件冒泡特性,将子元素的事件委托给父元素处理

三大优势

  1. 减少注册次数:只需绑定一个父元素

  2. 提高性能:节省内存资源

  3. 支持动态元素:自动处理新增子元素

实现原理

<ul id="list"><li>选项1</li><li>选项2</li><li>选项3</li>
</ul><script>
document.getElementById('list').addEventListener('click', function(e) {// 检测实际点击的元素if(e.target.tagName === 'LI') {console.log('点击了:', e.target.textContent);e.target.style.backgroundColor = 'pink';}
});
</script>

关键技巧

// 精确判断被点击的子元素
if(e.target.tagName === 'LI') { /* 处理逻辑 */ }// 或使用类名判断
if(e.target.classList.contains('item')) { /* 处理逻辑 */ }

十七、页面加载事件

两种加载事件对比

事件类型触发时机绑定对象适用场景
load页面所有资源加载完毕(包括图片等)window需要操作图片/外部资源时
DOMContentLoadedHTML解析完成(无需等样式/图片)document需要尽早操作DOM元素时

代码实现

// 1. load事件(等待所有资源)
window.addEventListener('load', function() {console.log('所有资源加载完成');// 可安全操作图片尺寸等
});// 2. DOMContentLoaded(推荐)
document.addEventListener('DOMContentLoaded', function() {console.log('DOM解析完成');// 可立即操作DOM元素const btn = document.querySelector('button');btn.disabled = false;
});

⚠️ 常见问题解决

脚本放在head中无法获取元素?
使用DOMContentLoaded事件包裹操作:

document.addEventListener('DOMContentLoaded', function() {// 这里可以安全获取DOM元素const element = document.getElementById('content');
});


✅ 事件系统核心要点总结

黄金实践原则:

  1. 动态元素处理使用事件委托

  2. DOM操作使用 DOMContentLoaded

  3. 资源相关操作使用 load

  4. 表单处理记得 preventDefault()

  5. 事件传播控制使用 stopPropagation()


📝 高频面试题速答

  1. Q:事件委托有什么好处?

    A:减少注册次数提高性能,支持动态元素,节省内存资源

  2. Q:如何找到实际触发事件的元素?

    A:使用 e.target.tagName 或 e.target.classList

  3. Q:load 和 DOMContentLoaded 的区别?

    A:load 等待所有资源加载,DOMContentLoaded 只需HTML解析完成

  4. Q:如何阻止表单自动提交?

    A:在submit事件中使用 e.preventDefault()

  5. Q:事件冒泡有什么应用场景?

    A:事件委托就是利用冒泡机制实现的

十八、页面滚动事件

核心概念

  • scroll事件:当页面或元素滚动时触发

  • 使用场景

    • 滚动到指定位置显示/隐藏元素

    • 实现滚动进度指示器

    • 懒加载图片等资源

获取滚动位置

// 1. 监听整个页面滚动
window.addEventListener('scroll', function() {// 获取页面垂直滚动距离(被卷去的头部)const scrollTop = document.documentElement.scrollTop;console.log('页面滚动距离:', scrollTop);// 示例:滚动超过100px显示返回顶部按钮if(scrollTop > 100) {backToTopBtn.style.display = 'block';}
});// 2. 监听元素内部滚动
const div = document.querySelector('.scrollable');
div.addEventListener('scroll', function() {// 获取元素内部滚动位置console.log('元素垂直滚动:', this.scrollTop);console.log('元素水平滚动:', this.scrollLeft);
});

⚠️ 注意事项

  1. 页面滚动距离通过 document.documentElement.scrollTop 获取

  2. 元素内部滚动通过元素的 scrollTop 属性获取

  3. 这些属性可读写,可通过赋值修改滚动位置


十九、页面尺寸事件

核心概念

  • resize事件:当窗口尺寸改变时触发

  • 使用场景

    • 响应式布局调整

    • 移动端横竖屏切换

    • 图表等可视化组件重绘

获取窗口尺寸

window.addEventListener('resize', function() {// 获取视口宽度(不含滚动条)const viewportWidth = document.documentElement.clientWidth;// 获取视口高度(不含滚动条)const viewportHeight = document.documentElement.clientHeight;console.log(`窗口尺寸: ${viewportWidth} x ${viewportHeight}`);// 示例:移动端布局调整if(viewportWidth < 768) {navbar.classList.add('mobile-mode');} else {navbar.classList.remove('mobile-mode');}
});

⚠️ 注意事项

clientWidth/clientHeight 获取的是可视区域尺寸,不包含滚动条


二十、元素尺寸与位置

1. 尺寸属性

属性包含内容是否只读使用场景
offsetWidth内容+padding+border只读获取元素完整宽度
offsetHeight内容+padding+border只读获取元素完整高度
clientWidth内容+padding(不含边框)只读获取可视内容宽度
clientHeight内容+padding(不含边框)只读获取可视内容高度

2. 位置属性

属性说明基准点
offsetTop元素顶部距离定位父元素的距离最近的定位父元素
offsetLeft元素左侧距离定位父元素的距离最近的定位父元素
scrollTop元素内容垂直滚动距离元素顶部
scrollLeft元素内容水平滚动距离元素左侧

3. 获取元素位置方法

// getBoundingClientRect() 返回元素相对于视口的位置
const rect = element.getBoundingClientRect();
console.log(`元素位置: top: ${rect.top}px, left: ${rect.left}px,width: ${rect.width}px,height: ${rect.height}px
`);// 获取元素相对于文档的位置
const docTop = rect.top + window.scrollY;
const docLeft = rect.left + window.scrollX;

⚠️ 关键注意事项

  1. 隐藏元素的尺寸获取结果为0

  2. offsetTop/offsetLeft 的基准是最近的定位父元素

  3. 若无定位父元素,则相对于文档左上角计算

  4. getBoundingClientRect() 的值随滚动实时变化


二十一、滚动位置属性对比

属性作用是否可修改适用对象
scrollTop获取/设置垂直滚动距离✅ 可读写页面/可滚动元素
scrollLeft获取/设置水平滚动距离✅ 可读写页面/可滚动元素
pageYOffset获取页面垂直滚动距离❌ 只读window (等同于scrollTop)
pageXOffset获取页面水平滚动距离❌ 只读window

示例:平滑滚动到顶部

// 方式1:修改scrollTop
function scrollToTop() {const top = document.documentElement.scrollTop;if(top > 0) {window.scrollTo(0, top - 50); // 每次上移50pxrequestAnimationFrame(scrollToTop);}
}// 方式2:使用scrollTo API
backToTopBtn.addEventListener('click', () => {window.scrollTo({top: 0,behavior: 'smooth' // 平滑滚动});
});

✅ 核心要点总结

📝 高频面试题速答

  1. Q:如何获取页面滚动距离?

    A:document.documentElement.scrollTop

  2. Q:offsetWidth和clientWidth的区别?

    A:offsetWidth包含边框,clientWidth不包含边框

  3. Q:如何让元素滚动到指定位置?

    A:设置元素的scrollTop属性或使用window.scrollTo()

  4. Q:getBoundingClientRect()获取的位置是否包含滚动距离?

    A:否,它返回相对于视口的位置,需加上scrollY/scrollX获取文档位置

  5. Q:如何监听窗口尺寸变化?

    A:使用window.addEventListener('resize', callback)


🧠 记忆口诀

"三尺寸四位置,滚动监听要牢记"

  • 三尺寸:offset、client、scroll

  • 四位置:offsetTop/Left、scrollTop/Left

  • 两事件:scroll、resize

http://www.xdnf.cn/news/15042.html

相关文章:

  • imx6ull-系统移植篇2—— U-Boot 命令使用(上)
  • vscode.window对象讲解
  • “SRP模型+”多技术融合在生态环境脆弱性评价模型构建、时空格局演变分析与RSEI 指数的生态质量评价及拓展应用
  • 深入解码 Docker 镜像与容器的奇妙世界
  • 飞算JavaAI:革新Java开发的智能助手
  • React Three Fiber 实现 3D 模型点击高亮交互的核心技巧
  • Microsoft Word 中 .doc 和 .docx 的区别
  • mongodb 开源同步工具介绍
  • 项目开发日记
  • 锁的艺术:从Mutex到ReentrantLock,掌握并发编程的脉搏
  • java多线程环境下资源隔离机制ThreadLocal详解
  • 《PyQt6-3D:开启Python 3D编程新世界 2》
  • 多线程学习
  • 处理Web请求路径参数
  • 【笔记】使用 html 创建网址快捷方式
  • 计算机学科专业基础综合(408)四门核心课程的知识点总结
  • RabbitMQ 幂等性
  • 在vscode中和obsidian中使用Mermaid
  • esp32在vscode中仿真调试
  • 蓝桥云课 矩形切割-Java
  • ZW3D 二次开发-创建球体
  • [架构之美]虚拟机Ubuntu密码重置
  • C++ Lambda 表达式详解
  • 建造者模式
  • Linux驱动06 --- UDP
  • 8.2.3希尔排序
  • CTI-CRYOGENICS Cryo-Torr®高真空泵安装、操作和维护说明
  • 国内如何考取Oracle大师
  • [2025CVPR]CCFS:高IPC数据集蒸馏的课程式粗细筛选技术解析
  • scp发送文件忽悠密码