用javascript写一个日历
1|0用javascript写一个日历
1|11. 选择器
selector | class | desc |
---|---|---|
calendarContainer | .calendar-container | 日历的显示块 |
calendarContainerH2 | .calendar-container h2 | 日历的年份文本显示 |
calendar | .calendar | 需要js插入日期的部分 |
calendarHiddenBtn | .calendar-hidden-btn | 将日历显示的动画按钮 |
shrinkBtn | .shrink-btn | 将日历隐藏的动画按钮 |
calendarBtn | all(.calendar-btn) | 获取了三个按钮包括向上一个月,向下一个月和显示全部月份 |
1|22. 定义变量
获取的当前的日期,用以标注日历中的当前日期,比如今天是2020年8月17号,则日历中的这一天可以相应标记。
变量名 | 描述 |
---|---|
currentYear | 获取当前的年份 |
currentCalendar | 获取当前的日期 |
currentMonth | 获取当前的月份 |
currentDate | 获取当前的日 |
year | 要渲染的年份 |
weekDays | 存储所有的星期字符串 |
months | 存储所有的月份字符串 |
1|3
日历以一年为单位来渲染,所以就需要一个函数参数来传递需要渲染的年份,function insertDate(year){}
,函数内容如下:
日历中的年份文本标题需要通过传入的年份参数动态更改,用dates绑定一个存储了一年中所有日期的数组,这个数组通过getAllDays函数获取,它也接收一个year年份参数,因为年份不同日历会不一样。monthsHTML存储一个html字符串用来插入每一个月份的html模板。
通过getAllDays函数获取一年中所有日期的数组,思路是获取这一年的第一天和最后一天,通过判断是否已经依次存入日期到最后一天来将所有日期存入数组,为了判断是否存入了最后一天,需要一个标记当前数组的最后一个元素,每次存入数组以后都将其与数组的最后一个元素绑定,在用它来与最后一天来判断。其中有一个addDays函数,它用来将天数加一天,以达到将每一天存入。
Date.getDate()方法返回的是日,是number对应 1 - 31
months数组中存储了一年的十二个月,通过foreach将数组中的每一个月遍历,叠加monthsHTML,会将12个月的html模板叠加入monthsHTML,其中每个月的星期都是7个,也需要循环加入,最后设置calendar的innerHTML。模板里的months_${index}
可以更好地追踪月份对应地dom,days_container
用来放置日节点。
插入日的思路是,date中有月、星期、日,在同一个一个date元素中getMonth获取了月份,getDate就获取了该月的日期,从浏览器控制台看date就能清楚
,而因为每一个月的1号对应的星期都不一样,所以必须插入相应的空白节点,dates中存储了所有日期对象,为每一个日期对象获取月份,并选择对应的dom节点,这样就可以在对应的节点中插入对应的日。Date.getDay()方法返回的是星期,也是number,不过是以0开始,即 0-6,通过判断当日为一号,而且不为星期一时,因为如果一号就是星期一那么就不需要插入空白节点了,空白节点的数量是刚好与一号对应的星期数相同,比如一号对应的是星期三,即getDay是2,而日历中也是星期一和星期二两处空白。createEmptySpot就是用来创建空白节点的函数,然后把空白节点插入对应月份的节点。插入完空白的节点,就需要插入日节点了,createDateEl为创建日节点的函数,然后插入到对应的月份节点。
上面函数创建的html模板是:
这个函数用day接收日期的日,创建的html模板为:
以上就已经完成了渲染一整年日历的工作,但是一般都是以一个月显示并且可以来回切换月份和年份,我以function calendarAnimation(){}
函数将这部分工作封装起来:
这部分为获取选择器,displayMonth
用来标记需要显示到面板的月份,没有被标记的月份需要隐藏起来,需要显示的节点用displayMonthEl来动态获取。而monthsContainer是用来获取日历显示面板的,用来更好的实现面板的移动或隐藏。
创建按钮点击事件,这里涉及到3个函数,containerBack函数用来显示日历面板,containerMove函数用来隐藏日历面板,monthChange用来切换显示的月份。
在monthChange函数中,传入event,用event.target来更好判断是哪个按钮在点击,向前一个月,则需要先让当前月份隐藏,让displayMonth--
变成前一个月并选择前一个月的节点显示,如果displayMonth<0
了就说明需要往前一年,这时就需要year - 1
并重新渲染日历了,需要重新调用insertDate(year),还要将应显示的月份设置为最后一个月。往后一个月的操作是同样的思路。
这两个函数是一个简单的移动动画
最后,获取你今天的日期,用以标注当日日期。
1|4总结
在这个项目中,让我对时间的操作有了很多的实践,getFullYear() getMonth() getDate() getDay()
。数组的forEach map
,后者会返回一个新的数组,可以用join
来将其组合成字符串,在${}
中如果内容是一个值会将其值输出。
最后,javascript是面向对象的,我却写得像面向过程,主要还是没有理解对象,不知道该如何选取对象,需要好好去理解一下,或许写一个小游戏的项目会帮助我的理解。
__EOF__

本文链接:https://www.cnblogs.com/flynn24/p/13518056.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现