change回调是唯一能实现“点击即关”的方案,需配合主动删除浮层;done和choose均触发过晚或不响应年月列表项点击,且需补监听年月列表项事件委托并处理z-index与遮罩干扰。

默认不会自动关闭,必须手动干预 DOM 或调整回调时机。laydate 的 done 回调触发太晚,choose 只响应「确定」按钮,真正能实现「点完就关」的是 change 回调配合主动清理浮层。
为什么 done 和 choose 都不行
done 在点击「确定」后才执行,用户还得额外点一次;choose 行为和 done 几乎一致,且不触发年份/月份列表项的点击——也就是说,type: 'year' 时点一个年份,choose 根本不进。这两个回调都违背「点击即关」的直觉操作流。
-
change是唯一在任意日期单元格、年份项、月份项被点击切换值时立即触发的回调(前提是值真变了) - 它比
done早得多,也比choose更灵敏,适合做即时响应 - 但注意:
change也会在左右年份切换时触发,所以别在里面做提交逻辑,只做 UI 同步和关闭
正确写法:用 change + $('.layui-laydate').remove()
核心就是两件事:更新输入框值 + 删掉浮层容器。不能依赖 showBottom: false 单独起作用,它只是隐藏底部按钮,不解决关闭问题。
- 务必设置
showBottom: false,否则底部按钮区域会拦截点击,导致change失效 - 用类名
$('.layui-laydate')删除,而不是带序号的 ID(如$('#layui-laydate4')),ID 不稳定且不可预测 - 多个 laydate 实例共存时,
$('.layui-laydate')会匹配全部,但实际只有一层是打开状态,安全
laydate.render({
elem: '#yearInput',
type: 'year',
format: 'yyyy',
showBottom: false,
change: function(value) {
$('#yearInput').val(value);
$('.layui-laydate').remove();
}
});
type 为 year 或 month 时的特殊处理
年份/月份选择器的列表项(如 .laydate-year-list li)默认不触发 change,除非你点的是当前高亮年份——这是 laydate 的隐藏限制:只有「值真正变化了」才进 change。所以单靠 change 仍可能漏掉点击。
- 补监听
.laydate-year-list li和.laydate-month-list li的点击事件 - 在监听里手动更新输入框并删浮层,和
change里的逻辑保持一致 - 不需要重复绑定,直接在
render外追加即可,DOM 是动态生成的,得用事件委托
// 补监听年份列表
layui.$(document).on('click', '.laydate-year-list li', function() {
var value = layui.$(this).text();
$('#yearInput').val(value);
$('.layui-laydate').remove();
});
// 补监听月份列表(同理)
layui.$(document).on('click', '.laydate-month-list li', function() {
var value = layui.$(this).text();
$('#monthInput').val(value);
$('.layui-laydate').remove();
});
容易被忽略的 z-index 和遮罩干扰
如果页面有 modal、loading 遮罩,或 body 设置了 overflow: hidden,.layui-laydate 容器可能被压在下面、不可见,或者 pointer-events 被禁用——这时点击根本不会触发 change,更别说关闭了。这不是代码逻辑问题,而是渲染层级问题。
- 检查浏览器开发者工具里
.layui-laydate是否被其他元素盖住 - 临时给它加
z-index: 999999 !important看是否恢复响应 - 避免在
fixed容器或 iframe 子页里直接初始化 laydate,易受父级样式穿透影响
真正难的不是写这几行代码,而是判断「当前浮层是不是用户正在看的那个」——比如快速连点两次日期控件,第一次的 change 可能还没执行完,第二次浮层已覆盖,$('.layui-laydate').remove() 就会误删正在用的那个。这种竞态需要更精细的作用域隔离,比如用 $(this.elem).closest('.layui-laydate') 替代全局类名选择器。











