input[type="date"]的min/max必须严格使用YYYY-MM-DD格式,否则静默失效;动态设置需用setAttribute而非直接赋值;需手动校验输入值并服务端二次验证。

input[type="date"] 的 min/max 必须是严格 YYYY-MM-DD 格式
浏览器对 min 和 max 属性的格式极其敏感,错一位就静默失效——不报错、不灰显、日历照常可点,但 checkValidity() 会返回 false。
-
"2026-09-05"✅ 正确(年4位、月2位、日2位,短横线分隔) -
"2026-9-5"❌ 被忽略(月份/日期缺零,字符串比较时可能反转逻辑) -
"2026/09/05"❌ 被忽略(斜杠非 ISO 8601 允许分隔符) -
"2026-09-05T00:00"❌ 被忽略(含时间部分,type="date"只接受纯日期)
常见翻车点:new Date().toISOString() 直接赋值 → 得到 "2026-09-05T11:22:33.456Z",必须用 .slice(0, 10) 或 .split('T')[0] 截断。
动态设置 min/max 必须用 setAttribute,不能只改 .min =
写 input.min = "2026-09-05" 在 Safari(尤其 iOS ≤ 15.5)和部分旧 Chrome 中,日历 UI 不刷新,用户仍能点选超限日期。
- 可靠写法:使用
input.setAttribute('min', '2026-09-05') - 或手动触发重绘:
input.dispatchEvent(new Event('input', { bubbles: true })),再加input.focus(); setTimeout(() => input.blur(), 10) - 如果当前
input.value已超出新max,浏览器不会自动清空,需显式判断:if (input.value && input.value > input.max) input.value = ''
min/max 只约束日历面板,拦不住手动输入和 JS 赋值
min/max 对键盘输入、粘贴、开发者工具修改、JS 直接赋值完全无效。Safari 甚至不触发原生提交校验提示。
- 监听
input事件做实时反馈:input.setCustomValidity('日期不能早于' + input.min) - 在
change事件中兜底重置:if (new Date(input.value) > new Date(input.max)) input.value = '' - 移动端
change触发不稳定,建议加blur事件兜底 - 服务端必须二次校验——这是唯一真正可靠的防线
联动起止日期时,min/max 必须同步清理
比如“结束日期 ≥ 开始日期”,只设 end.min = start.value 不够。
- 当用户清空
start时,必须同步执行end.removeAttribute('min')或end.min = '',否则end永远被卡住 - 用户可能手动输入
end早于start,需监听change并调用end.setCustomValidity()+end.reportValidity() - 避免仅靠字符串字典序比较(如
input.value ),跨时区下new Date(input.value)可能偏移一天;优先用input.valueAsNumber(非法时返回NaN)或严格格式化后比对
实际限制未来14天范围时,今天是 2026-09-05,max 应设为 2026-09-19,且所有环节都得按上述规则走一遍——格式、设置方式、事件监听、服务端兜底,漏一环就等于没限制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











