失焦校验需用Layui封装的form.on('change')而非原生blur,自定义规则必须返回错误字符串才能触发lay-form-danger类和红边框,且input须有name属性、正确声明lay-verify规则并调用form.render('input')。
失焦时触发校验但不依赖原生 blur 事件
直接给 input 绑定原生 blur 并调用 form.verify() 会失败——因为 layui 的验证逻辑依赖表单内部状态同步,而原生事件绕过了它的事件通道,导致 lay-form-danger 类不添加、提示不显示、甚至后续 form.val() 仍返回旧值。
正确路径是走 Layui 封装的 form.on('change', selector, fn):它在用户失焦且值实际变化时触发,天然契合“失焦即校验”场景,且与内部校验链路完全对齐。
- 必须用
data.elem获取 DOM 元素,避免this指向错乱 - 不要在回调里手动加
lay-form-danger类——Layui 会在校验失败后自动添加 - 若需对所有带校验的 input 统一处理,用属性选择器:
form.on('change', 'input[name][lay-verify]')
form.verify() 中如何让失焦校验生效并显示边框
Layui 默认只在 form.on('submit') 或用户主动点击提交时才执行完整校验流程。要让失焦时也触发样式反馈(如红色边框),关键是在 form.verify 规则中**显式返回错误字符串**,而非仅做逻辑判断。
例如定义一个长度校验规则:
form.verify({
maxlength: function(value, item) {
const max = parseInt(item.getAttribute('lay-maxlength') || '0');
if (max > 0 && value.length > max) {
return '超出最大长度限制'; // ← 必须返回字符串,否则无提示、无边框
}
}
});
再配合 HTML 中声明该规则:
<input name="title" lay-verify="required|maxlength" lay-maxlength="20">
- 返回
undefined或true表示通过,不会加红边框 - 返回非空字符串才会触发
lay-form-danger类和右侧图标 - 注意:内置规则如
required自带提示,但自定义规则必须手动返回提示文本
为什么 form.on('change') 后没看到红边框?常见漏点
即使绑了 form.on('change') 且规则返回了错误字符串,仍可能看不到红边框——大概率是以下三处之一没到位:
- 没调用
form.render('input'):动态插入或 JS 创建的 input,必须显式渲染才能启用 Layui 的事件和样式绑定 - input 缺少
name属性:Layui 的form.verify和form.on('change')都依赖name定位字段,无name则整个校验链路失效 - 校验规则名拼写错误或未在
lay-verify中声明:比如写了form.verify({ phoneRule: ... }),但 HTML 写的是lay-verify="phone",两者不匹配就等于没挂上规则
多个 tab 页中失焦校验只作用于当前页
当表单分散在多个 element.tab 标签页里,全局监听 form.on('change') 会导致非激活页的 input 也被校验,干扰用户体验,甚至触发错误滚动。
解决方法是限定事件作用域:不用全局选择器,改用当前激活面板下的子元素。
- 先获取当前显示的 tab 面板:
const $active = $('.layui-tab-content .layui-show'); - 再在该容器内初始化表单事件:
form.on('change', $active.find('input[name][lay-verify]').selector, ...)(注意:.selector是 jQuery 提供的字符串形式选择器) - 更稳妥的做法是为每个 tab 面板加唯一
id,并在form.on的 selector 中直接写死范围,如#tab-user input[name][lay-verify]
动态 tab 渲染后,记得在 tabs.on('tab') 回调里重新执行 form.render('input') 和事件绑定,否则新 tab 的 input 失焦不会触发任何校验。


















