企业小程序如何做_js完成日历

这篇文章主要介绍了js如何实现日历,帮助大家完成需求,提高对js的理解,感兴趣的朋友可以了解下

这周写自己的项目发现又用到日历了,加之自己毕业之后的第一个工作中遇到的任务也是需要写个日历(组员写了,我就不用写了)
今天就来好好折腾一下日历是怎么写的。

首先,我们看看 windows 的日历。发现总共有这么几个元素。先实现试试。

1.年份的选择、月份的选择
2.周一 ~ 周日(周日 ~ 周六)
3.日历格子 6*7 = 42

从数据的角度来分析日历的实现是比较简单的
1.我们需要显示一个当前时间的结构 - new Date()
2.我们需要显示当月的信息 - [星期(周一~周日),日期(1-[28,29,30,31])]
其中我们只要知道了每个月的 1日 是星期几,就能很容易地摆放后面的日子(万事开头难)。

我们最多需要 6 行来显示我们的日期,因为要第一排如果只包含本月的一天 6(上个月的) + (1 + 4*7),这样就五行了,当月天数若大于 29,就显示不下了 确定了 6 行之后,我们发现我们可能需要获取上个月,和下个月多出来的几天的摆放位置。 不同年份的不同月的 2月份,我们知道它的日期是不同的,所以我们还需要判断 平年还是闰年。

3.显示上个月,下个月的切换。我们发现需要有个函数来帮我们更新日历。

分析完之后,让我们跟着 新增/修改 一些代码。

 !DOCTYPE html 
 html lang="en" 
 head 
 meta charset="UTF-8" 
 meta name="viewport" content="width=device-width, initial-scale=1.0" 
 meta http-equiv="X-UA-Compatible" content="ie=edge" 
 title Document /title 
 style 
 .week-item {
 display: inline-block;
 width: 80px;
 height: 40px;
 line-height: 40px;
 border: 1px solid sandybrown;
 text-align: center;
 .date-item {
 display: inline-block;
 width: 80px;
 height: 40px;
 line-height: 40px;
 border: 1px solid beige;
 text-align: center;
 /style 
 /head 
 body 
 div 
 div 
 button id="preMonth" 上一月 /button 
 button id="nowYear" /button 
 button id="nowMonth" /button 
 button id="nowDate" /button 
 button id="nextMonth" 下一月 /button 
 /div 
 div id="weekLine" /div 
 div id="dateWrap" /div 
 /div 
 /body 
 script 
 // 工具方法 - start
 // 1.为了获得每个月的日期有多少,我们需要判断 平年闰年[四年一闰,百年不闰,四百年再闰]
 const isLeapYear = (year) = {
 return (year % 400 === 0) || (year % 100 !== 0 year % 4 === 0);
 // 2.获得每个月的日期有多少,注意 month - [0-11]
 const getMonthCount = (year, month) = {
 let arr = [
 31, null, 31, 30, 
 31, 30, 31, 31,
 30, 31, 30, 31
 let count = arr[month] || (isLeapYear(year) 29 : 28);
 return Array.from(new Array(count), (item, value) = value + 1);
 // 3.获得某年某月的 1号 是星期几,这里要注意的是 JS 的 API-getDay() 是从 [日-六](0-6),返回 number
 const getWeekday = (year, month) = {
 let date = new Date(year, month, 1);
 return date.getDay();
 // 4.获得上个月的天数
 const getPreMonthCount = (year, month) = {
 if (month === 0) {
 return getMonthCount(year - 1, 11);
 } else {
 return getMonthCount(year, month - 1);
 // 5.获得下个月的天数
 const getNextMonthCount = (year, month) = {
 if (month === 11) {
 return getMonthCount(year + 1, 0);
 } else {
 return getMonthCount(year, month + 1);
 // 工具方法 - end
 let weekStr = '日一二三四五六';
 weekArr = weekStr.split('').map(item = '星期' + item);
 // 插入星期 dom
 let weekDomStr = '';
 let oFragWeek = document.createDocumentFragment();
 weekArr.forEach(item = {
 let oSpan = document.createElement('span');
 let oText = document.createTextNode(item);
 oSpan.appendChild(oText);
 oSpan.classList.add('week-item');
 oFragWeek.appendChild(oSpan);
 let weekWrap = document.getElementById('weekLine');
 weekWrap.appendChild(oFragWeek);
 // 这里获得我们第一次的 数据 数组
 const updateCalendar = (year, month, day) = {
 if (typeof year === 'undefined' typeof month === 'undefined' typeof day === 'undefined') {
 let nowDate = new Date();
 year = nowDate.getFullYear();
 month = nowDate.getMonth();
 day = nowDate.getDate();
 // 更新一下顶部的年月显示
 document.getElementById('nowYear').innerHTML = year;
 document.getElementById('nowMonth').innerHTML = month + 1;
 document.getElementById('nowDate').innerHTML = day;
 // 生成日历数据,上个月剩下的的 x 天 + 当月的 28(平年的2月)或者29(闰年的2月)或者30或者31天 + 下个月的 y 天 = 42
 let res = [];
 let currentMonth = getMonthCount(year, month);
 let preMonth = getPreMonthCount(year, month);
 let nextMonth = getNextMonthCount(year, month);
 let whereMonday = getWeekday(year, month);
 if (whereMonday === 0) {
 whereMonday = 7
 // 感谢网友 luoyiming 的测试(哈哈!谢谢!):这里当 whereMonday 为 0 的时候会截取上月的所有数据
 let preArr = preMonth.slice(-1 * whereMonday)
 let nextArr = nextMonth.slice(0, 42 - currentMonth.length - whereMonday);
 res = [].concat(preArr, currentMonth, nextArr);
 // 上面经过我本人的测试是没有什么问题,接下来就是更新 dom 的信息的问题
 let hadDom = document.getElementsByClassName('date-item');
 if (hadDom hadDom.length) {
 let domArr = document.getElementsByClassName('date-item');
 for (let i = 0; i domArr.length; i++) {
 domArr[i].innerHTML = res.shift();
 } else {
 // 如果之前没有结构的话
 let str = '';
 for (let i = 0; i i++) {
 str += ' div 
 for (let j = 0; j j++) {
 str += ` span ${res.shift()} /span 
 if (j === 6) {
 str += ' /div 
 document.getElementById('dateWrap').innerHTML = str;
 updateCalendar();
 // 添加上一月,下一月事件
 let oPreButton = document.getElementById('preMonth');
 let oNextButton = document.getElementById('nextMonth');
 oPreButton.addEventListener('click', function () {
 let currentYear = +document.getElementById('nowYear').textContent;
 let currentMonth = +document.getElementById('nowMonth').textContent - 1;
 let currentDate = +document.getElementById('nowDate').textContent;
 if (currentMonth === 0) {
 updateCalendar(currentYear - 1, 11, currentDate);
 } else {
 updateCalendar(currentYear, currentMonth - 1, currentDate);
 oNextButton.addEventListener('click', function () {
 let currentYear = +document.getElementById('nowYear').textContent;
 let currentMonth = +document.getElementById('nowMonth').textContent - 1;
 let currentDate = +document.getElementById('nowDate').textContent;
 if (currentMonth === 11) {
 updateCalendar(currentYear + 1, 0, currentDate);
 } else {
 updateCalendar(currentYear, currentMonth + 1, currentDate);
 /script 
 /html 

发现用 dom 直接操作而不是通过 mvvm 框架实现确实还是比较蛋疼的,以下是这次实现的效果。

实现一个功能的时候,从数据的层面分析,有时候会比较容易理解

以上就是js实现日历的详细内容,更多关于js 日历的资料请关注凡科其它



扫描二维码分享到微信