原生的日期选择器不会因滚动自动关闭,这是浏览器规范行为;唯一可控方式是滚动时对聚焦的该输入框调用blur()收起面板,需防抖且在移动端safari中效果有限。

date input 在滚动时不会自动关闭,这是浏览器原生行为
HTML <input type="date"> 的日期选择器(calendar picker)由浏览器原生实现,**没有 API 控制其显隐状态**,也不响应页面滚动事件。滚动时它不关闭,不是 bug,而是规范行为——Chrome、Edge、Safari 均如此,且无法通过 CSS 或 JS 直接干预弹出层。
能做的只有“主动收起”:用 blur() 模拟失焦关闭
虽然不能监听“滚动触发关闭”,但可以在滚动开始时主动让 input 失去焦点,从而收起日期面板。注意:这仅在 picker 当前已展开且 input 仍聚焦时有效。
-
input.blur()是最可靠的方式,比document.activeElement?.blur()更直接 - 需加防抖,避免滚动中高频调用(例如 100ms 内只执行一次)
- 仅对当前聚焦的 date input 生效,其他 input 不受影响
- 移动端 Safari 对
blur()响应较慢或无效,属已知限制
const dateInput = document.querySelector('input[type="date"]');
let scrollTimer;
window.addEventListener('scroll', () => {
if (document.activeElement === dateInput) {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(() => dateInput.blur(), 100);
}
});
为什么 preventDefault 或 pointer-events 无效
有人尝试给 body 加 pointer-events: none 或拦截 scroll 事件并 preventDefault(),这些都不可行:
-
preventDefault()在scroll事件上无效果(该事件默认不可取消) -
pointer-events: none会禁用整个页面交互,且不影响已弹出的 native picker 层(它在 top layer,z-index 独立) - CSS 伪元素(如
::-webkit-calendar-picker-indicator)只能改图标,不能控制面板开关
真正可控的替代方案:自建日期选择器
如果必须滚动即关、支持键盘导航、适配移动端,原生 input[type="date"] 就不该用。推荐:
- 用
<input type="text">+flatpickr/dayjs+ 自定义日历弹层 - 监听
scroll、click(非 input 区域)、focusout,统一调用picker.close() - 注意 aria 标签和键盘焦点管理,否则可访问性受损
- 代价是体积增加约 15–30KB(gzip 后),且需维护样式兼容性
原生 date input 的“不可控”恰恰是它的设计前提:它被当作操作系统级控件对待。想绕过这个前提,就得放弃原生。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











