min/max 必须为严格 yyyy-mm-dd 格式字符串,如“2026-08-11”,否则浏览器静默忽略;动态设置需用 setattribute 或触发重绘;联动时需同步清空已失效的 min/max。

min/max 必须是严格 YYYY-MM-DD 字符串
浏览器只认形如 "2026-08-11" 的字符串,少一个零("2026-8-11")、多一个字符("2026-08-11T00:00")、用斜杠("2026/08/11")或点分隔("11.08.2026"),整个属性就被静默忽略——UI 不变、输入不拦、也不报错,但 checkValidity() 会返回 false。
常见翻车点:
-
new Date().toISOString()直接赋值 → 得到"2026-08-11T15:22:33.456Z",必须.slice(0, 10) - 手拼
"2026-" + (month + 1) + "-" + date→ 月份/日期没补零,变成"2026-8-11",字典序比较时它 >"2026-08-11",逻辑反转 - 后端返回
"2026/08/11"或"11-08-2026"→ 浏览器当没看见
动态设置必须用 setAttribute 或手动触发重绘
写 input.min = "2026-08-11" 看似生效,但在 Safari(尤其 iOS ≤ 15.5)和部分旧版 Chrome 中,日历 UI 不刷新,用户仍能点选超限日期。
真正可靠的方式只有:
- 用
input.setAttribute('min', '2026-08-11')—— 触发 DOM 属性变更,强制重绘控件 - 或
input.min = '2026-08-11'后加触发: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 清空逻辑不能漏
做“结束日期不能早于开始日期”这类联动时,只设 end.min = start.value 是不够的。一旦用户清空了 start,end.min 必须同步清空(设为 ''),否则 end 将永远无法选择任何值——因为 min 被卡在一个已不存在的日期上。
正确写法示例:
start.addEventListener('change', () => {
end.min = start.value || '';
});
end.addEventListener('change', () => {
if (end.value && start.value && end.value
<h3>min/max 不阻止手动输入,必须 JS + 服务端双校验</h3>
<p>原生 <code>min</code>/<code>max</code> 只影响日历面板(禁用范围外选项),但完全不限制键盘输入、粘贴、或 JS 赋值。用户仍可键入 <code>"1900-01-01"</code> 并提交,Chrome/Firefox 提交时才拦截并提示,Safari 甚至不触发校验。</p>
<p>所以必须配合:</p>
- 监听
input或change事件,调用input.checkValidity()或手动比对new Date(input.value)是否在范围内 - 用
input.setCustomValidity()给出明确反馈 - 服务端必须二次校验——前端限制纯属体验优化,不可信任
最易被忽略的是:移动端 WebView(尤其旧版 iOS)对 min/max 支持极差,可能完全不渲染限制逻辑,JS 校验那层根本不能省。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











