min/max 属性必须为严格 YYYY-MM-DD 格式字符串,错一位即静默失效;动态设置需用 setAttribute 或触发重绘;JS 和服务端双重校验不可少。

min/max 属性必须是严格 YYYY-MM-DD 字符串
浏览器对 min 和 max 的格式极其敏感,错一位就静默失效——不是报错,而是完全不生效,日历照常可点、输入框照常可填。常见翻车点包括:
-
"2026-9-4"❌(月份/日期缺零,字符串比较会出错) -
"2026/09/04"❌(斜杠分隔,被忽略) -
"2026-09-04T00:00"❌(带时间部分,直接丢弃) -
new Date().toISOString()直接赋值 → 得到带T和时区的字符串,必须用.slice(0, 10)或.split('T')[0]截断
推荐生成方式:const today = new Date(); const isoDate = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`,避免时区偏移和格式隐患。
动态设置必须用 setAttribute 或触发重绘
直接写 input.min = "2026-09-04" 在 Safari(尤其 iOS ≤ 15.5)和部分旧 Chrome 中,UI 不刷新,用户仍能点选超限日期。可靠做法只有两种:
- 用
input.setAttribute('min', '2026-09-04')—— 触发 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 = ''
联动起止日期时 min/max 必须双向同步且清空
仅设 end.min = start.value 是不够的。用户行为不可控,必须覆盖所有边界情况:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
- 当
start被清空时,必须同步执行end.removeAttribute('min')或end.min = '',否则end将永远被卡住 - 用户可能先填
end再填start,所以start的change里也要补一次end.min = start.value - 用户手动输入
end早于start,需在end.change中用end.setCustomValidity('结束日期不能早于开始日期')+end.reportValidity()实时拦截 - 移动端 Safari 的
change触发不稳定,建议加blur事件兜底
JS 校验才是真约束,浏览器提示靠不住
min/max 只影响日历弹窗和表单提交时的原生提示,但以下行为完全绕过它:
- 手动键入任意合法格式日期(如
"1900-01-01") - 粘贴超限值
- 开发者工具直接改 DOM 值
- JS 脚本赋值:
input.value = "3000-01-01"
真实项目中必须做两层校验:
- 前端监听
input事件做实时检查:if (new Date(e.target.value) > maxDate) e.target.setCustomValidity('日期太晚') - 服务端必须重新解析并验证范围,不可信任任何前端传来的
date字段
最易被忽略的是:不同浏览器对同一 min/max 的视觉反馈不一致——Safari 可能灰掉但允许输入,Chrome 禁用日历项却不限制键盘,别假设用户只会点日历。


















