需手写html表格+js实现可控月视图日历:用new date()获取当前年月,计算1号星期几并偏移对齐周一,用new date(year,month+1,0).getdate()获取当月天数,分上/本/下月三类渲染,事件委托绑定点击,兼容ie11需避免字符串解析日期。

怎么用纯 HTML + JavaScript 渲染当月日历表格
不能只靠 <input type="date"> —— 它不支持月视图定制,也没法高亮节假日、添加事件点。真要可控的日历,得手写表格结构 + JS 控制日期逻辑。
核心是:用 new Date() 获取当前年月 → 算出该月 1 号是周几 → 补齐上月尾部空白格 → 拼出 6 行 × 7 列的 <table>。<ul>
<li>别直接用 <code>Date.prototype.getDay() 返回值当列索引:它周日返回 0,而多数日历把周一当首列,得手动偏移(比如 (dayIndex + 6) % 7)
31 硬写:new Date(year, month + 1, 0).getDate() 更可靠(利用“下月第 0 天”即为本月最后一天)other-month),方便 CSS 区分样式如何让日历自动定位到指定年月(比如点击「上月」按钮)
关键不是重载页面,而是更新 currentYear 和 currentMonth 变量后重新调用渲染函数。月份增减必须用 setMonth() 或数学计算,不能直接对 month 加减后传给 new Date(year, month) —— 否则可能跳到非法月份(比如 new Date(2024, 13) 会变成 2025 年 1 月,但中间状态不可控)。
- 安全做法:
const d = new Date(currentYear, currentMonth); d.setMonth(d.getMonth() - 1);再取d.getFullYear()和d.getMonth() - 避免用字符串拼接年月(如
"2024-02")再解析,容易因时区导致日期偏移一天 - 点击切换时,建议禁用按钮并加 loading class,防止快速连点触发多次渲染(尤其在操作 DOM 较多时)
为什么点击日期没反应?常见事件绑定失效原因
动态生成的 <td> 元素,如果在渲染后才去 <code>querySelectorAll('td').forEach(...) 绑事件,大概率绑不上 —— 因为节点还没插入 DOM,或后续重新渲染又清掉了。
- 正确做法:用事件委托,给日历容器(如
<table id="calendar">)绑定 <code>click,再用event.target.closest('td')判断是否点中日期格 - 注意排除空白格:
if (target.classList.contains('other-month')) return; - 别忘了给
<td> 加 <code>tabindex="0"和键盘事件(Enter/Space),否则无法满足基础可访问性要求怎么兼容 IE11 或旧版 Safari 的日期 API 行为差异
new Date('2024-03-01')在 IE11 里会返回Invalid Date,因为只认/分隔或无分隔格式('2024/03/01'或'20240301')。所有涉及字符串转日期的地方都得兜底。- 统一用
new Date(year, monthIndex, day)构造,彻底避开字符串解析 - 检查
isNaN(date.getTime())替代date instanceof Date && !isNaN(date),更兼容老浏览器 - IE11 不支持
Element.classList的部分方法(如toggle带第二个参数),改用add/remove显式控制
月视图日历真正的复杂点不在画格子,而在日期边界计算和跨浏览器时间处理 —— 少一个
+1或多一个时区转换,就可能某天显示错位或点击无效。动手前先写几个测试用例:闰年2月、12月切到下年1月、时区为 UTC+8 以外的设备表现。 - 统一用
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











