safari中input[type="date"]的min/max需用setattribute或dispatchevent更新ui,且必须严格yyyy-mm-dd格式;min/max不拦截手动输入,需监听input事件校验;联动时清空start后须同步移除end的min属性。

input[type="date"]的min/max在Safari中UI不更新
直接赋值input.min = "2026-06-23"在 Safari(尤其 iOS ≤ 15.5 和 macOS Safari 16.x)中不会刷新日历控件,用户仍能点选超限日期。Chrome 和 Firefox 通常能响应,但不可依赖。
真正跨浏览器可靠的方式只有:
• 用input.setAttribute('min', '2026-06-23')——触发属性变更,强制重绘
• 或先赋值再手动触发重绘:input.min = '2026-06-23'; input.dispatchEvent(new Event('input', { bubbles: true }))
• 若已存在input.value且超出新max,必须显式清空:if (input.value && input.value > input.max) input.value = ''
min/max格式错误导致静默失效,checkValidity()返回false
浏览器对input[type="date"]的min/max极其挑剔:只认严格YYYY-MM-DD格式。错一位、多字符、带时间或斜杠,全被忽略——UI不灰、输入不拦、控制台无报错,但checkValidity()返回false。
常见翻车点:
• new Date().toISOString()直接赋值 → 得到"2026-06-23T08:46:12.345Z",必须.slice(0, 10)
• 手拼"2026-6-23" → 字符串比较时"2026-6-23" > "2026-06-23"为true,逻辑反转
• 后端返回"2026/06/23"或"23-06-2026" → 浏览器当没看见
用户仍能手动输入非法日期,min/max不是拦截器
min/max只约束日历控件选择和提交校验,完全不限制键盘输入、粘贴、删除重输。用户可轻松输入"2025-01-01"到max="2024-12-31"的框里,且无实时反馈。
要补上这个缺口:
• 监听input事件(不是change),用input.valueAsNumber判断是否合法(非法日期返回NaN)
• 若input.value > input.max,立即修正:input.value = input.max
• 配合setCustomValidity()提供明确提示,例如input.setCustomValidity('不能晚于' + input.max)
• 移动端 Safari 对change触发不稳定,建议blur事件兜底校验
联动日期时min/max清空逻辑常被漏掉
做“结束日期不能早于开始日期”这类联动,只设end.min = start.value远远不够。一旦用户清空start,end.min会被卡在一个已不存在的日期上,导致end永远无法选任何值。
必须同步处理:
• 监听start的change和blur事件,若start.value === '',立刻执行end.removeAttribute('min')或end.min = ''
• 监听end的input事件,若end.value && start.value && end.value ,调用<code>end.setCustomValidity('结束日期不能早于开始日期')并立即end.reportValidity()
• 注意:input.value是字符串,比较时需确保格式一致,避免"2026-6-23" 这种字典序陷阱











