dom事件
约 2495 字大约 8 分钟
2026-06-02
手写笔记







一、基础概念
1.1 事件流定义
- Q:什么是事件流?
- A:当某个事件发生时,网页元素会监听到该事件,这些元素触发事件的顺序。
⚠️ 核心笔记:当一个元素发生某个事件时,该元素的所有祖先元素都发生了该事件,与视觉效果无关。
1.2 事件流的两个阶段
| 阶段 | 触发顺序 | 说明 |
|---|---|---|
| 事件冒泡 | 先触发最内层元素,再依次触发外层元素 | 浏览器默认事件流 |
| 事件捕获 | 先触发最外层元素,再依次触发内层元素 | 需手动开启 |
1.3 事件源与事件目标
事件源/事件目标:事件目标阶段的元素,即实际触发事件的最内层元素。
二、事件注册(绑定事件)
2.1 DOM0级事件注册(旧标准)
- 语法:
dom.on+事件名 = 函数(如div.onclick = function(){}) - 本质:将函数作为DOM元素的属性
- 移除事件:
dom.onclick = null或dom.onclick = undefined
2.2 DOM2级事件注册(新标准)
- 语法:
dom.addEventListener(事件名, 处理函数, 是否捕获)- 第三个参数:
false=冒泡阶段(默认),true=捕获阶段
- 第三个参数:
- 兼容:IE8及以下不兼容,需用
attachEvent/detachEvent - 移除事件:
dom.removeEventListener(事件名, 处理函数)- ⚠️ 注意:如果要移除事件,不能使用匿名函数,必须传入具名函数的引用。
2.3 DOM0与DOM2事件注册的核心区别
| 对比项 | DOM0级 | DOM2级 |
|---|---|---|
| 同一事件多个处理程序 | 不支持,后写的会覆盖先写的 | 支持,按注册顺序依次执行 |
| 事件阶段控制 | 只能在冒泡阶段触发 | 支持手动选择冒泡/捕获阶段 |
| 匿名函数移除 | 直接赋值null即可 | 无法移除匿名函数 |
三、事件对象
3.1 事件对象的获取
- 标准浏览器:通过事件处理函数的第一个形参获取
- IE旧版本:通过
window.event获取 - 兼容写法:
function(e) { e = e || window.event; }
3.2 事件对象通用成员
| 属性/方法 | 说明 | 手写重点 |
|---|---|---|
target / srcElement | 事件源(实际触发事件的元素) | ✅ 事件委托核心:通过给祖先元素注册事件,在处理函数中判断target来区分不同子元素,常用于动态生成元素的事件绑定 |
currentTarget | 当前目标元素,等价于this | 绑定事件的那个元素 |
type | 字符串,获取事件类型(如click/mouseover) | |
preventDefault() / return false | 阻止浏览器默认行为 | 如阻止链接跳转、表单提交、右键菜单 |
stopPropagation() | 阻止事件冒泡 | 防止事件向上传递到祖先元素 |
eventPhase | 获取事件所处的阶段 | 1=捕获阶段 2=事件目标阶段 3=冒泡阶段 |
四、作业讲解:事件对象实战
(核心考察:事件委托、阻止默认行为、阻止冒泡、事件源判断)
五、鼠标事件
5.1 鼠标事件分类
| 事件名 | 触发规则 | 手写区分要点 |
|---|---|---|
click | 左键单击触发;输入框聚焦回车可触发;右键、div右键无法触发click | 由mousedown+mouseup组合生成单击 |
dblclick | 鼠标快速双击左键触发 | 连续短间隔两次单击 |
mousedown | 按下鼠标任意按键瞬间触发 | 左/中/右键全部生效 |
mouseup | 抬起鼠标任意按键触发 | 和mousedown成对 |
mouseover | 光标移入元素触发 | ✅冒泡:父→子移动,父触发out、子触发over |
mouseout | 光标移出元素触发 | 冒泡:子离开向上触发父out |
mousemove | 光标在元素内持续移动高频触发 | 移动1px即触发,注意性能优化 |
mouseenter | 光标进入元素触发 | ❌不冒泡,子元素进出不影响父 |
mouseleave | 光标离开元素触发 | 不冒泡,与enter配对 |
5.2 MouseEvent事件对象
功能键与按键标识
| 属性 | 说明 |
|---|---|
altKey | 布尔,触发时是否按下Alt键 |
ctrlKey | 布尔,触发时是否按下Ctrl键 |
shiftKey | 布尔,触发时是否按下Shift键 |
button | 0=左键,1=中键滚轮,2=右键 |
五组坐标属性
| 分组 | 属性 | 参考基准 |
|---|---|---|
| page | pageX/pageY | 整个文档页面左上角,滚动不改变数值 |
| client | clientX/clientY | 浏览器可视窗口左上角(配合可视区尺寸使用) |
| offset | offsetX/offsetY | 当前元素内容内边距左上角 |
| screen | screenX/screenY | 电脑物理屏幕左上角 |
| movement | movementX/movementY | 仅mousemove有效,相对上次鼠标偏移 |
六、作业讲解:星星评分、商品放大镜(实战项目)
七、键盘事件
7.1 键盘三类原生事件
| 事件 | 触发时机 | 细节 |
|---|---|---|
keydown | 按下任意键触发,长按连续重复触发 | 功能键、字符键全识别 |
keypress | 仅可打印字符键按下触发 | Ctrl/Shift/方向键等功能键无效 |
keyup | 松开任意按键触发,长按松手只执行1次 |
⚠️ 笔记重点:
keydown/keypress中e.preventDefault()阻止默认行为,输入框无法输入文本。
7.2 KeyboardEvent事件对象
| 属性 | 说明 | 使用推荐 |
|---|---|---|
code | 物理按键编码(如KeyA),适配键盘布局 | ✅ 新标准推荐 |
key | 按键输出字符,区分大小写(a/A) | ✅ 业务开发首选 |
keyCode/which | 老式数字按键编码 | ❌ 官方废弃,不推荐 |
八、作业讲解:键盘案例(坦克移动、限制数字输入框)
九、其他常用事件
9.1 表单事件
| 事件 | 触发条件 | 关键特点 |
|---|---|---|
focus | 元素获取焦点(点击/Tab切换) | 不冒泡 |
blur | 元素失去焦点 | 不冒泡 |
submit | 仅<form>标签内,点击提交/回车触发 | 仅绑定form生效 |
change | 内容修改+失去焦点后触发 | 延迟更新 |
input | 内容实时变化立刻触发 | 即时响应,搜索框常用 |
💡 手写页面规范:CSS应该写到页面顶部,JS应该写到页面底部。
9.2 Window全局事件(部分DOM元素也可绑定)
| 事件 | 触发时机 |
|---|---|
load | window.load:页面全部资源(图片/样式/脚本)加载完毕;img.load:单张图片加载完成 |
DOMContentLoaded | DOM树构建完成即触发,不等图片/样式,比load更早 |
beforeunload | 页面刷新/关闭前触发,可弹窗阻止关闭 |
unload | 页面正式销毁关闭时执行 |
scroll | 窗口/元素滚动持续触发;通过scrollTop/scrollLeft读写滚动距离 |
resize | 浏览器窗口尺寸变化持续触发,配合窗口尺寸API使用 |
contextmenu | 右键唤起系统菜单,可阻止默认禁用右键 |
copy/cut/paste | 复制、剪切、粘贴剪贴板事件 |
文档生命周期:
document.readyState→loading(加载中)→interactive(可交互,触发DOMContentLoaded)→complete(资源全加载,触发load)
9.3 窗口/屏幕尺寸API
| 属性 | 含义 |
|---|---|
window.innerWidth / innerHeight | 浏览器可视窗口宽高(包含滚动条) |
window.outerWidth / outerHeight | 整个浏览器窗口(含标题栏、边框)尺寸 |
window.screen.width / screen.height | 电脑物理屏幕分辨率尺寸 |
document.documentElement.clientWidth/clientHeight | 页面可视区宽高(不含浏览器边框、滚动条) |
十、作业:自定义右键菜单、折叠面板
十一、补充知识点
11.1 offset系列属性
offsetParent:获取元素第一个非static定位的祖先元素,无则指向body;body.offsetParent === nulloffsetLeft/offsetTop:当前元素相对于offsetParent左上角的偏移像素;父级为body时等价相对整个页面offsetWidth / offsetHeight:包含边框+内边距+内容,不含外边距
11.2 client系列属性
clientWidth / clientHeight:不含边框、不含滚动条,包含内边距+内容
11.3 scroll系列属性(滚动相关)
scrollWidth / scrollHeight:元素完整内容尺寸(超出可视区也计入,不含边框)scrollLeft / scrollTop:内容滚动出去的距离(可读可写,scroll事件常用)
11.4 getBoundingClientRect()
返回DOMRect对象,存储元素相对可视视口的top/left/right/bottom/width/height坐标。
11.5 原生获取元素相对页面绝对坐标
function getPagePosition(dom) {
var left = dom.offsetLeft;
var top = dom.offsetTop;
var parent = dom.offsetParent;
while(parent) {
left += parent.offsetLeft;
top += parent.offsetTop;
parent = parent.offsetParent;
}
return {x: left, y: top}
}11.6 滚动相关API
滚动距离读取
window.scrollX === window.pageXOffset:页面横向滚动距离,等价根元素scrollLeftwindow.scrollY === window.pageYOffset:页面纵向滚动距离,等价根元素scrollTop
滚动控制方法
| 方法 | 作用 |
|---|---|
scrollTo(x, y) | 绝对坐标滚动,直接定位到页面指定位置 |
scrollBy(dx, dy) | 相对偏移滚动,在当前位置基础上增减距离 |
resizeTo/resizeBy | 修改浏览器窗口尺寸(仅部分浏览器支持) |
11.7 事件模拟
- 简易模拟:
dom.click()/form.submit() - 通用模拟:
dom.dispatchEvent(事件实例)
十二、核心总结
- 事件流核心:默认冒泡(内→外),可手动开启捕获(外→内);事件会沿DOM树传递,与视觉层级无关。
- 事件绑定:优先使用DOM2级
addEventListener,支持多处理程序和阶段控制;移除事件必须使用具名函数。 - 事件对象核心:
target是实际触发元素,currentTarget是绑定元素;preventDefault阻止默认行为,stopPropagation阻止冒泡。 - 事件委托:利用事件冒泡将子元素事件委托给父元素,是动态生成元素事件绑定的最优方案。
- 常用事件:鼠标事件区分冒泡/不冒泡;键盘事件优先用
key/code;页面事件DOMContentLoaded比load更早执行,resize/scroll配合尺寸API。 - 尺寸区分
- offset:含边框;client:不含边框;scroll:完整内容尺寸不含边框
- inner=浏览器可视区,outer=浏览器整体,screen=物理屏幕尺寸
- 位置与滚动:
offset系列相对定位父级,getBoundingClientRect相对视口;scrollTo绝对定位,scrollBy相对偏移。
