日历表格需用table严格实现:thead固定7列周标题,首行补空td对齐当月1号星期几,末行补空td确保满6行;日期存data-date属性防解析错误;移动端设min-height和padding保障点击区域。

用 table 搭建日历表格结构,必须带和空单元格占位
日历表格不是简单画个 7×6 的格子就行。浏览器渲染时,table 的列对齐依赖于每行 td / th 数量一致,否则会出现错列、宽度崩塌。必须显式写出 thead(含周几标题),并在第一行补足「上月尾部日期」对应的空 td,最后一行补足「下月开头日期」之后的空 td。
常见错误是只渲染当月日期,导致首周从周二开始却没留周一的空格——结果整行向左偏移,视觉完全错乱。
- 每周固定 7 列,
th 写死 ["日","一","二","三","四","五","六"]
- 计算当月 1 号是星期几(
new Date(year, month, 1).getDay()),这个值就是需要前置的空 td 个数(注意:周日是 0)
- 总行数不硬编码为 6;先算出当月天数(
new Date(year, month + 1, 0).getDate()),再结合起始 weekday 推出实际需几行
getDay() 和 getDate() 混用容易搞反月份和日期边界
JavaScript 的 Date 构造函数中,月份是 0 起始(0 = 一月),但 getDate() 返回的是 1 起始的日期数。这两个“1”含义完全不同,混用就会跳月或跳日。
典型翻车场景:想获取 2024 年 3 月最后一天,写成 new Date(2024, 3, 0).getDate() —— 这其实取的是 4 月的第 0 天,即 3 月 31 日,看似对,但逻辑已错;正确写法应是 new Date(2024, 3, 0)(即 2024-04-00 → 自动回滚为 2024-03-31),再调 getDate()。但更稳妥的是统一用 new Date(year, month + 1, 0).getDate() 算当月天数。
anything-to-html
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
下载
-
new Date(2024, 2, 1) 是 2024-03-01(不是 2 月)
-
new Date(2024, 2, 0) 是 2024-02-29(自动回滚到上月最后一天)
- 跨年计算别直接拼字符串,用
setFullYear() 更安全,避免 2024-13-01 这种非法日期静默转成 2025-01-01
点击某日触发回调时,必须从 DOM 元素上反推真实日期,不能只信 textContent
日历表格里会同时出现上月尾、本月、下月头的数字,比如 28、29、30、1、2……这些文本本身不含月份信息。如果仅靠 td.textContent 做判断,点到 “1” 就无法知道它是本月 1 号还是下月 1 号。
解决办法是在生成每个 td 时,把完整日期作为自定义属性存下来,例如 data-date="2024-03-01" 或 data-year="2024" data-month="2" data-day="1"。点击时读这个属性,而不是解析文本。
- 不要用
innerText 或正则从文本提取数字再拼日期——闰年、跨月、不同长度的月份都会让逻辑脆弱
- 如果用
data-date,建议统一用 ISO 格式(YYYY-MM-DD),方便后续直接传给 new Date()
- 服务端返回的日期若带时区,前端用
new Date().toLocaleDateString("sv-SE") 可稳定输出 ISO 格式字符串
移动端点击区域太小,td 必须设 min-height 和 padding
桌面端看着正常的 td,在手机上经常点不中——因为默认 td 高度由字号撑开,而小屏下字体缩放后内容高度可能不足 24px,远低于触控建议最小尺寸(44×44px)。
单纯加 font-size 不解决问题,会导致布局撑开或文字溢出。应该用 min-height + padding 组合保证可点击区域达标,同时用 text-align: center 和 vertical-align: middle 居中内容。
- 推荐最小点击尺寸:
min-height: 44px; padding: 8px;(上下各 8px,内容区净高 ≥28px)
- 避免用
line-height 控制高度,它在多行或弹性布局下行为不稳定
- 加
user-select: none 防止长按唤起文字选择菜单
日期计算本身不难,难的是边界条件全落在「月首/月尾+周首/周尾」的四个交点上。漏掉任意一个,比如 2024 年 2 月 1 号是周四,那前面要空 4 个格,后面要补够 6 行——这种组合稍不留意就少一行或多一行。
table 的列对齐依赖于每行 td / th 数量一致,否则会出现错列、宽度崩塌。必须显式写出 thead(含周几标题),并在第一行补足「上月尾部日期」对应的空 td,最后一行补足「下月开头日期」之后的空 td。th 写死 ["日","一","二","三","四","五","六"]
new Date(year, month, 1).getDay()),这个值就是需要前置的空 td 个数(注意:周日是 0)new Date(year, month + 1, 0).getDate()),再结合起始 weekday 推出实际需几行getDay() 和 getDate() 混用容易搞反月份和日期边界Date 构造函数中,月份是 0 起始(0 = 一月),但 getDate() 返回的是 1 起始的日期数。这两个“1”含义完全不同,混用就会跳月或跳日。new Date(2024, 3, 0).getDate() —— 这其实取的是 4 月的第 0 天,即 3 月 31 日,看似对,但逻辑已错;正确写法应是 new Date(2024, 3, 0)(即 2024-04-00 → 自动回滚为 2024-03-31),再调 getDate()。但更稳妥的是统一用 new Date(year, month + 1, 0).getDate() 算当月天数。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
new Date(2024, 2, 1) 是 2024-03-01(不是 2 月)new Date(2024, 2, 0) 是 2024-02-29(自动回滚到上月最后一天)setFullYear() 更安全,避免 2024-13-01 这种非法日期静默转成 2025-01-01textContent
td.textContent 做判断,点到 “1” 就无法知道它是本月 1 号还是下月 1 号。td 时,把完整日期作为自定义属性存下来,例如 data-date="2024-03-01" 或 data-year="2024" data-month="2" data-day="1"。点击时读这个属性,而不是解析文本。innerText 或正则从文本提取数字再拼日期——闰年、跨月、不同长度的月份都会让逻辑脆弱data-date,建议统一用 ISO 格式(YYYY-MM-DD),方便后续直接传给 new Date()
new Date().toLocaleDateString("sv-SE") 可稳定输出 ISO 格式字符串td 必须设 min-height 和 padding
td,在手机上经常点不中——因为默认 td 高度由字号撑开,而小屏下字体缩放后内容高度可能不足 24px,远低于触控建议最小尺寸(44×44px)。font-size 不解决问题,会导致布局撑开或文字溢出。应该用 min-height + padding 组合保证可点击区域达标,同时用 text-align: center 和 vertical-align: middle 居中内容。min-height: 44px; padding: 8px;(上下各 8px,内容区净高 ≥28px)line-height 控制高度,它在多行或弹性布局下行为不稳定user-select: none 防止长按唤起文字选择菜单前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










