抽屉关闭需兼顾多种方式:遮罩层点击默认不关闭以防误触,esc键须监听document并管理焦点,×按钮需语义化html和aria,移动端手势要精准判断区域与位移阈值。

抽屉关闭触发方式:点击遮罩层还是按钮?
抽屉(drawer)是否响应遮罩层点击关闭,取决于交互设计意图。默认不关闭更安全——避免用户误点背景导致内容丢失。若需支持,必须显式监听 document 或遮罩层的 click 事件,并用 event.target 判断点击位置是否在抽屉容器外。
- 遮罩层(
.drawer-overlay)设为position: fixed; z-index: 1000;,宽度/高度 100%,背景半透明 - 抽屉主体(
.drawer-panel)设更高z-index(如 1001),并添加pointer-events: auto; - 监听遮罩层
click时,不要直接close(),先检查event.target === overlayEl,防止点击抽屉内部也触发关闭
ESC 键关闭抽屉:必须加 keyboard 事件监听和焦点管理
Escape 键关闭是基础体验,但容易漏掉两个关键点:事件监听未绑定到 document,以及抽屉打开后焦点未移入。
- 用
document.addEventListener('keydown', handleKeydown),不能只绑在抽屉元素上(它可能不在 tab 顺序中) -
handleKeydown中判断event.key === 'Escape',再调用关闭逻辑 - 抽屉
open后,立即panelEl.focus()或聚焦第一个可交互子元素(如panelEl.querySelector('button, input, [tabindex]')) - 关闭时记得
removeEventListener,或用{ once: true }避免重复绑定
右上角 × 按钮关闭:DOM 结构和语义不能少
看似最简单的关闭方式,最容易出可访问性问题。纯 × 文本按钮没有语义,屏幕阅读器无法识别功能。
- 按钮必须是
<button type="button"><span aria-hidden="true">×</span><span class="sr-only">关闭抽屉</span></button> -
sr-only类需含position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; - 点击后应触发同一种关闭函数,不要写三套逻辑;推荐统一调用
closeDrawer()并在其中重置状态、清空定时器、恢复 body 滚动等
移动端手势关闭:滑动阈值与 preventDefault 要谨慎
在 iOS Safari 或 Android Chrome 上做下拉关闭抽屉,touchmove 事件容易和页面滚动冲突。直接 preventDefault() 会禁用整个页面滚动,必须精确控制。
- 仅当抽屉已展开且用户在抽屉顶部区域(如前 80px)开始拖动时,才启用手势识别
- 记录
touchstart的clientY,在touchmove中计算位移差,超过50px再触发关闭 - 仅对抽屉容器调用
event.preventDefault(),不要作用于document或body - 务必在
touchend后重置所有手势状态变量,否则下次打开可能残留上次的偏移量
preventDefault,任一环节都会让关闭行为失效或伤害体验。真正难的是边界条件的处理,而不是开关本身。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











