input[type="date"]的min/max必须严格为yyyy-mm-dd格式,否则被静默忽略;动态设置需用setattribute或dispatchevent触发重绘;用户仍可手动输入超限值,须监听事件校验并服务端二次验证。

min/max 必须是严格 YYYY-MM-DD 格式,错一位就失效
浏览器对 input[type="date"] 的 min 和 max 属性极其敏感:只认形如 "2026-08-11" 的字符串。写成 "2026/08/11"、"2026-8-11"、"2026-08-11T00:00" 或 "11-08-2026",属性会被静默忽略——日历不灰、输入不拦、也不报错,但 checkValidity() 会返回 false。
常见翻车点:
-
new Date().toISOString()直接赋值 → 得到"2026-08-11T05:48:22.123Z",必须用.split('T')[0]或.slice(0, 10)截断 - 手拼
"2026-8-11"→ 字符串比较时"2026-8-11" > "2026-08-11"成立,导致范围逻辑反转 - 后端返回
"2026/08/11"→ 浏览器当无效值丢弃
动态设置必须用 setAttribute,直接赋值常不刷新 UI
在 JavaScript 中写 input.min = "2026-08-11" 看似简单,但在 Safari(尤其 iOS ≤ 15.5)和部分旧版 Chrome 中,日历控件不会重绘,用户仍能看到并点选超限日期。
真正可靠的做法只有两种:
- 用
input.setAttribute('min', '2026-08-11')—— 触发 DOM 属性变更,强制重绘 - 或手动触发更新:
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 = ''
用户仍能手动输入超限值,必须监听 input 和 change 事件校验
min/max 只影响日历弹窗的可选状态和表单提交时的原生校验,完全不限制键盘输入、粘贴或 JS 赋值。用户可以键入任意合法格式日期(比如 "1900-01-01"),提交前也不会提示。
实操建议:
- 监听
input事件做即时反馈:input.setCustomValidity()标记无效状态,配合form.reportValidity()触发提示 - 在
change事件中兜底重置:if (new Date(input.value) maxDate) input.value = '' - 避免只依赖
blur:用户可能跳过失焦直接点提交按钮 - 注意时区陷阱:
new Date(input.value)在跨时区场景下可能偏移一天,优先用input.valueAsNumber(非法时返回NaN)或字符串字典序比较
Safari 对 min/max 支持不稳定,移动端尤其要测试
iOS Safari(尤其是 iOS 16 之前)常忽略 min/max,或仅在打开日期选择器时部分生效。这不是 bug,而是其原生 picker 实现未严格遵循规范。Chrome 和 Firefox 会在日历中灰显不可选日期,Safari 则可能全量显示,仅在提交时校验。
应对策略:
- 不要只靠 UI 灰显来传达限制,需配合文字提示(如“最早可选:2026-08-11”)
- 联动场景(如“结束日期不能早于开始日期”)中,一旦清空开始日期,必须同步清空
end.min,否则end将永远无法选择任何值 - 服务端必须二次校验——前端所有限制都可被绕过,包括禁用 JS、改 DOM、curl 直接 POST
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











