layui数据表格点击搜索查询表单刷新两遍的问题详解
今天我又遇到了一个问题,layui 的数据表格 reload 时刷新两遍的问题。点击“查询”,页面会闪烁一下,并且搜索条中输入的条件会清空。
上边用了 layui form 做了一个搜索条,下边用 layui table 实现数据表格。
浏览器_form_submit
以下是带有输入框和确认按钮的表单:
即使是这样简单的一段代码,在你点击 “提交” 时,也会产生一个HTTP请求。
比如,我把以上代码保存在桌面的文本文档(txt 文件)中,并重命名为 search.html :
接着,右击该文件,选择 打开方式为 Google Chrome:
接着点击 提交:
浏览器地址栏中发生了变化,增加了查询参数 ?newsTitle=Hello~。
该现象产生的原因是 在缺省情况下 method="GET" (了解更多 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/form#attr-method)
如果修改为,点击“提交”按钮以后,浏览器地址栏URL将不发生重定向。
这是 + 组合使用的效果,浏览器解析到这样的标签组合,就会给这个按钮提供将表单数据提交给服务器的功能!!
当你不指定 的 type 属性时,它的默认值就是 submit:
以上截图截取自 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/button
解决方案一:拆散form_submit组合
既然浏览器检查到元素 + ,会自动提供提交表单(即刷新页面)的功能,那我们就通过修改 button 来取消这种默认行为!!
使用
或者
替换
layui.form.on_lay-filter
首先,执行 form.js 中的初始化函数:
以上代码使用的是 jQuery 语法:
$(selector).on(event,childSelector,data,function)
代码解释:
在包含class="layui-form"的元素上添加 "submit" 事件的处理程序,事件发生时的回调函数是submit;
在所有包含lay-submit属性的元素上添加 "click" 事件的处理程序,事件发生时的回调函数也是submit;了解更多 CSS选择器 https://www.runoob.com/cssref/css-selectors.html
form.js中的submit函数
页面正常显示之后,用户点击“查询”时,回调函数 submit 被触发,以下对比一下 submit 触发时的局部变量:
包含 lay-submit 属性的元素的 click 事件触发回调函数 |
包含 class="layui-form" 的表单的submit事件触发回调函数 |
|
|---|---|---|
button = $(this) //当前触发的按钮 |
|
|
elem = button.parents(ELEM).eq(0) //当前所在表单域 |
|
找不到 |
verifyElem = elem.find('*[lay-verify]') //获取需要校验的元素 |
找不到,因为我没在 上加 lay-verify 属性 |
没找到 |
formElem = button.parents('form')[0] //获取当前所在的 form 元素,如果存在的话 |
|
undefined |
★filter = button.attr('lay-filter') //获取过滤器 |
"search" | undefined |
★this |
|
|
首先,包含 lay-submit 属性的元素的 click 事件触发回调函数时,运行到 submit 函数的最后:
layui.js中的Layui.prototype.event
两次执行自定义模块事件 Layui.prototype.event 的本地变量对比:
触发事件 |
触发事件 |
|
|---|---|---|
| events | "submit(search)" | "submit(undefined)" |
| var that = this | |
|
//提取事件过滤器字符结构 |
||
eventName = (modName + '.'+ events).replace(filter[0], '')//获取事件名称 |
"form.select" | "form.select" |
//获取过滤器名称 |
"search" | "undefined" |
是否触发自定义模块事件的关键判断在
其中 config.event 对应 form.on('submit(search)', function (data) { ... }); 这段代码:
因为,此时 key 的值为 "search"
所以 key === '' 结果为 false,所以发生“短路”(即&& layui.each(item, callback)不会执行。)
触发事件 |
触发事件 |
|
|---|---|---|
| filterName | "search" | "undefined" |
(filterName && key === filterName) |
true | false |
&& layui.each(item, callback) |
会执行 | 不会执行 |
总而言之,form.on('submit(search)', function (data) {...}); 中回调函数 table.reload('dataTable', { where: data.field }); 只执行了一次。
结论,到底是怎么刷新两遍的?
所以刷新两遍就是:
table.reload('dataTable', { where: data.field });第一次刷新;
$(selector).on_return false
因为 form.js 中用的是 jquery 语法注册事件,且我跟了一遍源码后发现,用户函数中返回值,在每一层调用中都有返回,所以,可以简化 search.html 为
此时,点击“提交”不会提交form表单,即不会产生http请求。
参考文档:
javascript事件中'return false'详解
https://www.w3.org/TR/DOM-Level-3-Events/#event-flow-default-cancel
解决方案2:return false取消事件默认行为(default action)
本文之前就已经提供了 解决方案一:拆散form_submit组合,现在提供第二种思路 return false取消事件默认行为(default action)。
★ 在本例中,与 上的 click 事件相关联的默认操作(default action)将表单(