防抖必须加在table.reload()调用前,而非done回调或loading中;正确做法是点击时用时间戳判断间隔,如let lastSearchTime=0; if(Date.now()-lastSearchTime

table.reload() 前必须加防抖,不能靠回调节流
快速点两次搜索按钮就发两个 table.reload() 请求,不是后端扛不住,是前端没拦住触发源头。Layui 的 reload() 本身是异步非阻塞的,等它执行完再解锁或判断毫无意义——防抖必须落在调用它之前。
常见错误是把防抖逻辑写在 done 回调里,或者试图用 loading: true 挡住二次点击,这些都无效。真正起作用的是在用户点击那一刻就掐断后续动作。
- 用闭包变量 + 时间戳最轻量:
let lastSearchTime = 0;,点击时判断if (Date.now() - lastSearchTime ,然后更新lastSearchTime = Date.now(); - 若用了
form.on('submit', ...)触发搜索,同样适用该锁;且必须在table.reload()的done回调里重置锁,否则翻页、排序可能被误拦截 - 别用
lodash.debounce这类通用函数——它依赖定时器,在layer.confirm等异步确认场景下容易丢失上下文,闭包时间戳更可控
toolbar 按钮点击刷新页面?先查是否套在 form 里
点击工具栏按钮后整个页面跳转或刷新,90% 是因为按钮意外包裹在 标签内,或者用了 但没声明 type="button"。浏览器对表单内无 type 的按钮默认执行 submit,直接触发热刷新。
- 所有 toolbar 按钮统一用
,禁用默认行为 - 检查 HTML 结构,确认 toolbar 区域(包括
script[type="text/html"]模板)没被包裹 - 如果必须用
,务必加onclick="return false;",否则#会滚动到顶部,某些旧 WebView 下还会触发重载
操作列按钮连点导致弹窗叠叠乐?行级状态锁比全局锁更准
表格里“编辑”“删除”这类按钮连点,弹出两个 layer 窗口,甚至删了两遍数据,问题不在请求发没发出去,而在事件入口没做隔离。全局时间戳锁对同一行多次点击无效——用户可能连续点同一行的按钮。
- 用
obj.tr.data('clicking', true)绑定行级锁定状态,点击入口第一行判断:if (obj.tr.data('clicking')) return; - 在
layer.confirm的yes回调里执行业务逻辑,完成后立刻obj.tr.removeData('clicking') - 如果用了
layer.open且不带确认步骤,要在success回调里清理状态,否则关闭弹窗后该行仍被锁定 - 别用
disabled禁用按钮 DOM——Layui 表格重绘后按钮重建,禁用状态丢失
reload 后 toolbar 按钮失效?事件委托才是正解
table.reload() 会清空并重建整个表格 DOM,包括 toolbar 区域,而 table.on('toolbar(*)') 只在初始化时绑定一次,新生成的按钮节点没有监听器,自然点不动。
- 改用事件委托:
$(document).on('click', '[lay-event="add"]', function(){ ... }),确保动态插入的按钮也能响应 - 避免重复绑定:在绑定前先
$(document).off('click', '[lay-event="add"]'),或用唯一命名空间如.toolbarAdd - 如果 toolbar 使用了
toolbar: '#barDemo'模板,确保#barDemo是全局存在的独立 DOM 节点,不要随表格一起被reload()清掉
真正容易被忽略的是:防抖和事件委托必须配合使用——防抖管“点太快”,委托管“点不到”,少一个都会在 reload 或快速操作后露出破绽。











