先聊个常见问题:用 Layui 写表单提交,明明在回调里写了 `layer.msg`,结果就是不弹,页面还直接刷新了。排查到最后,八成是同一个原因。 form.on('submit()') 里不弹 layer.msg 是什么问题 最常见的原因就一个:没阻止表单的默认提交行为。浏览器一发现你在监听按钮
最常见的原因就一个:没阻止表单的默认提交行为。浏览器一发现你在监听按钮,还顺手把表单给提了,那它自己也就跟着提交了。页面一跳转、一刷新,layer.msg() 根本没机会执行。
这得搞清楚:Layui 的 form.on 只是一个监听事件,它不是拦截器。你拦不拦,浏览器可不管。
长期稳定更新的攒劲资源: >>>点此立即查看<<<

所以,一定要在回调函数的第一行写 e.preventDefault()(这里的 e 就是事件参数),把浏览器的默认提交行为按住。用 return false 也能达到效果,但从语义上来说,e.preventDefault() 更清晰、更标准。
当然,这里还有几个细节要留意:
layer 模块加载了。 Layui 2.8+ 版本默认内置,但老版本需要检查是否手动调用过 layui.use('layer')。没加载,当然没反应。layer.msg() 的位置必须准确。 如果采用 AJAX 提交,消息提示一定要放在 success 回调里,千万别写在 form.on 的外层。那相当于请求还没回来就弹,自然看不到。layer.msg()。 尤其是在 iOS Safari 上,多次堆叠容易直接失效,甚至不显示。再来说说 iframe 弹窗。很多同学用 layer.open 打开一个 iframe 类型的弹窗后,发现子页面的 DOM 元素根本拿不到。这很正常,因为子页面渲染在另一个独立的 JS 上下文里,你直接用 $('#form') 当然不行。
常规做法是这样的:
top.layer.getChildFrame('body', index) —— 这是推荐做法,兼容性最好。通过这个方法,可以拿到子页面的 body 对象,然后再用它来查找表单元素。var formParam = body.find('#myForm').serialize();,就能把整个表单的数据一次性序列化出来,方便提交。body.find('#username').val() 这样获取具体字段的值。前提是,这个 ID 确实在子页面里存在,而且没有重复。form.submit() 提交。 这个方法没有返回值,很难控制后续流程,比如提交后需要关闭弹窗、刷新表格,容易搞乱时机。这个场景最典型了:编辑或新增完数据,弹窗要关,父页面的表格要刷新。关键是要拿到当前弹窗的索引,并且告诉父页面去重载数据。
一个常见坑:直接写 parent.location.reload()。这么做会粗暴地刷新整个页面,用户的筛选条件和当前页码全丢了,体验很差。应该优先用 table.reload() 做精准刷新:
var index = layer.open({ ... }); 这个 index 就是当前弹窗的唯一身份标识。layer.close(index); 关闭即可。parent.layui.table.reload('yourTableId', { where: { status: 'active' } }); 来刷新。这样做既能保留表格的当前配置,又能带上你的筛选条件(比如只显示“启用”状态的用户)。parent.layer.getFrameIndex(window.name) 来获取索引,比手动存变量要安全可靠得多。很多同学踩过这个坑:点“取消”按钮,结果是表单被提交了。这不是 Layui 的 bug,是 HTML 的默认行为:没有声明 type 属性的 元素,浏览器一律当成 type="submit" 处理。
这意味着,在弹窗里如果放了“保存”和“取消”两个按钮,而“取消”按钮没写 type,那它点击时就会触发表单的 submit 事件。
解决方案很简单:
type 属性: 。这样它就只是个普通按钮,不会触发提交。type 这个硬属性。lay-submit: 这个 Layui 属性,只给真正要提交的按钮加上。其他按钮(取消、重置等),一律显式设置 type="button"。真正麻烦的不是弹窗关不关,而是那个没写 type 的按钮。它不会在调试时给你任何错误提示,只会在用户点“取消”的时候,默默地提交一次空数据。排查起来,简直让人头大。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述