bottomsheet 表单错误列表通过 fixed 定位 + transform 动画实现,结构化渲染错误项并支持点击聚焦与滚动定位,兼顾键盘避让、滚动禁用、遮罩关闭、无障碍等细节。

在移动端 H5 中用 BottomSheet 展示表单校验错误列表,核心是:用轻量 DOM + CSS 动画实现底部弹起效果,配合 JS 聚焦错误、滚动定位、键盘避让等细节。不依赖重型 UI 库(如 Vant/Element Plus)也能做得流畅。
1. 结构与基础样式:用 fixed + transform 实现 BottomSheet
BottomSheet 本质是一个固定定位、从底部滑入的容器。关键点是避免使用 position: absolute(易被父级 overflow 截断),优先用 fixed,并用 transform: translateY() 做动画:
- 外层容器设
position: fixed; bottom: 0; left: 0; right: 0; z-index: 999; - 内部内容区加
transform: translateY(100%); transition: transform 0.3s cubic-bezier(0.3, 0, 0.1, 1); - 显示时移除 translateY 或设为 0;隐藏时设为 100%
- 加
backdrop-filter: blur(6px);或半透黑遮罩提升视觉层次(iOS Safari 支持良好)
2. 错误列表渲染:结构化错误数据 + 可点击跳转
不要只罗列文字。把校验结果整理成数组,每项含字段名、中文提示、关联 DOM ID(用于点击后 focus):
const errors = [
{ field: 'phone', message: '手机号格式不正确', id: 'input-phone' },
{ field: 'password', message: '密码至少6位', id: 'input-pwd' }
]
渲染时用 <ul class="error-list"><li>...</li></ul>,每项绑定 onclick="focusField(item.id)",点击后聚焦对应输入框并滚动到可视区域。
3. 关键交互细节:聚焦、滚动、键盘避让
移动端弹窗最常被忽略的是软键盘干扰:
- 点击错误项后,调用
el.focus(),再用el.scrollIntoView({ behavior: 'smooth', block: 'center' })确保输入框居中可见 - 监听
focusin事件,若 BottomSheet 正在显示,自动收起(避免双层弹窗) - 安卓 WebView 或部分 iOS 版本中,
scrollIntoView可能失效,可 fallback 到el.getBoundingClientRect().top + window.scrollY - 100手动 scroll - 提交失败后立即 show BottomSheet,但需防重复触发(加节流或状态锁)
4. 兼容与体验优化
真实项目中要注意这些“小坑”:
- 禁用 body 滚动:BottomSheet 显示时加
document.body.style.overflow = 'hidden',隐藏时恢复;iOS Safari 需额外加touchmove.preventDefault()防止穿透滚动 - 点击遮罩关闭:遮罩层(
div.overlay)绑定click隐藏弹窗,但要阻止冒泡到内部列表项 - 空状态友好:无错误时不 show,有错误才触发;支持「全部修复后自动关闭」逻辑
- 无障碍:给 BottomSheet 加
role="dialog" aria-modal="true" aria-labelledby="error-title",提升读屏体验










