验证失败后需在form.on('submit')中手动查找首个错误项并滚动:先限定范围(如当前tab面板),再遍历lay-verify元素,用自定义规则或checkValidity判断,最后focus()并scrollIntoView()。
验证失败后怎么让页面自动滚动到第一个错误项
layui 的 form.verify 只负责校验逻辑,不控制焦点或滚动。验证失败时表单没反应,是因为你没手动处理 dom 行为。
实操上得监听 form.on('submit(...)'),在回调里拦截默认提交,遍历所有带 lay-verify 的元素,用 checkValidity() 或自定义规则判断,找到第一个验证失败的 <input> 或 <select>,然后调用 .focus() 和 .scrollIntoView({ behavior: 'smooth' })。
- 别依赖
form.render('verify')—— 它只重绘验证图标,不触发校验 - 注意:Layui 2.8+ 的
form.val()不会主动触发验证,得自己调form.verify()或用form.validate()(需额外引入) - 如果用了
required原生属性,部分浏览器会自动聚焦,但行为不一致,建议统一用 JS 控制
为什么 form.on('submit') 里 $('input').hasClass('layui-form-danger') 总是空
因为 layui-form-danger 类名不是验证失败立刻加上的——它只在用户「失焦」(blur)或「点击提交」后,由 Layui 内部的 form.render() 后续逻辑添加,且时机晚于 submit 回调执行。
所以你在 submit 回调里直接查 class,大概率查不到。正确做法是:不依赖 class,改用验证函数返回值或 DOM 属性判断。
- 对每个必填字段,检查
$(elem).val().trim() === ''(配合required属性) - 对自定义规则字段,复用你定义在
form.verify里的函数,传入当前值手动执行 - 更稳的方式:给每个表单项加
name,用form.val('form-filter')拿全部值,再逐个过验证逻辑
多个 tab 页里的表单验证失败,怎么只定位当前 tab 的错误项
常见场景:用 element.tab 切换表单页签,但验证失败后焦点跳到了第一个 tab 里的输入框,用户体验断裂。
关键在限定查找范围。不要全局 $('input[lay-verify]'),而是先拿到当前激活的 tab 面板(比如通过 $('.layui-tab-content .layui-show')),再在这个容器内找验证项。
- 确保每个 tab 面板有唯一标识,比如
id="tab-user"、id="tab-contact" - 在 submit 回调里,先
const $activePanel = $('.layui-tab-content .layui-show'),再$activePanel.find('input[lay-verify], select[lay-verify]') - 如果用了动态渲染 tab,注意
layui-tab-content下的layui-show类可能还没同步,可改用layui-this找对应 tab 标题的href属性值来定位面板
移动端 iOS Safari 上 scrollIntoView 失效或滚动错位
iOS Safari 对 scrollIntoView 的支持较弱,尤其在软键盘弹出后,视口计算容易出错,导致错误框被遮住或滚过头。
绕过方式是手动计算偏移并用 scrollTop,而不是依赖原生方法。
- 用
elem.getBoundingClientRect().top + window.pageYOffset - 100(减去约 100 是预留键盘高度) - 对
body或外层滚动容器(如.layui-layer-content)设置scrollTop,而不是直接操作window - 加上
setTimeout延迟 100ms,等键盘收起动画结束再滚动(iOS 键盘收起会触发resize事件,但时机不稳定)
复杂点在于:不同机型键盘高度不同,且 Layui 弹层、iframe、固定定位布局都会干扰滚动基准。最保险的做法,是把错误定位逻辑和具体容器绑定,而不是写成通用函数。


















