文章目录
- 1、原生web实现
- 效果图
- html
- JavaScript
- style
- vue2实现
- html
- JavaScript
1、原生web实现
效果图
html
<div class="box">
<div class="week">
<div>星期日</div>
<div>星期一</div>
<div>星期二</div>
<div>星期三</div>
<div>星期四</div>
<div>星期五</div>
<div>星期六</div>
</div>
<div class="calendar_box">
<div id="idBox" class="calendar"></div>
</div>
<div class="y_m_box">
<div id="idYBtn" class="y_btn_box"></div>
<div id="idMBtn" class="m_btn_box"></div>
<div id="idShow" class="show_box"></div>
</div>
</div>
JavaScript
let y = undefined,
m = undefined;
// 创建日期
function creationDate(y, m, d) {
let arr = [];
for (let i = 1; i < d + 1; i++) arr.push(calendar.solar2lunar(y, m, i));
return arr;
}
// 准备创建的日期数范围
function createCalendar(y, m) {
let y1 = y,
y2 = y,
y3 = y,
m1 = m - 1,
m2 = m,
m3 = m + 1,
d1 = 0,
d2 = 0,
d3 = 0,
moth = [1, 3, 5, 7, 8, 10, 12],
days = () => y % 2 === 0 ? 29 : 28,
dayss = (val) => moth.includes(val) ? 31 : 30;
if (m === 1) (y1 = y - 1, m1 = 12);
if (m === 12) (y3 = y + 1, m3 = 1);
d1 = m1 === 2 ? days() : dayss(m1);
d2 = m2 === 2 ? days() : dayss(m2);
d3 = m3 === 2 ? days() : dayss(m3);
let arr1 = creationDate(y1, m1, d1),
arr2 = creationDate(y2, m2, d2),
arr3 = creationDate(y3, m3, d3),
len2 = arr2.length,
nWeek1 = arr2[0].nWeek,
nWeek3 = arr2[len2 - 1].nWeek;
nWeek1 = nWeek1 === 7 ? 0 : arr2[0].nWeek;
nWeek3 = nWeek3 === 6 ? 0 : nWeek3 === 7 ? nWeek3 - 1 : 6 - nWeek3;
for (let i = arr1.length - 1; nWeek1 > 0; i--) {
arr2.unshift(arr1[i]);
nWeek1--;
}
for (let i = 0; i < nWeek3; i++) arr2.push(arr3[i]);
return arr2;
}
// 初始化
function init() {
let date = new Date();
y = date.getFullYear();
m = date.getMonth() + 1;
let arr = createCalendar(y, m)
str = '';
for (let i = 0; i < arr.length; i++) {
let item = arr[i],
lunar = '';
lunar = item.IDayCn === '初一' && !item.festival ? item.IMonthCn : item.festival ? item.festival : item.IDayCn;
str += `<div class="item">
<div class="south">${item.cDay}</div>
<div class="lunar" style="color: ${item.festival ? '#0000ff' : ''}">${lunar}</div>
</div>`;
}
idBox.innerHTML = str;
let idYBtnStr = '',
idMBtnStr = '';
for (let i = 2003; i < 2030; i++) idYBtnStr += `<div class="y_item">${i}</div>`;
for (let i = 0; i < 12; i++) idMBtnStr += `<div class="m_item">${i + 1}</div>`;
idYBtn.innerHTML = idYBtnStr;
idMBtn.innerHTML = idMBtnStr;
idShow.innerHTML = `<span>${y}</span> <span>${m}</span>`;
}
// 执行初始化
init();
// 选择年份
idYBtn.onclick = ({ target: { textContent, className } }) => {
y = Number(textContent);
assignment(y, className);
}
// 选择月份
idMBtn.onclick = function ({ target: { textContent, className } }) {
m = Number(textContent);
assignment(m, className);
}
// 赋值
function assignment(val, className) {
if (className === 'm_item' || className === 'y_item') {
idShow.innerHTML = `<span>${y}</span> <span>${m}</span>`;
createCalendar(y, m);
}
}
npm插件下载指令
npm install js-calendar-converter --save
或
cnpm install js-calendar-converter --S
注释
1、在全局定义变量
y和变量m,两个变量分别用来存储当前选中的年份和月份,初始值为undefined。
2、定义名为createCalendar的函数,此函数是本例的重要函数之一。在本函数中会创建当前月的上月和下一月的所有数据,并且会组合成日历的形式返回准确数据,也就是是说会把数据组成七天的形式返回。本月前部分不够那就不上,后半部分不够也不上,总之会组成35或42个数据长度。
第一步
定义三个保存年份值的变量,为什么要定义三个呢?有可能你会想,那年份不都一样吗!可惜年份不一定一样。当传入的月份是1时,年份就要倒退1年,并且取上一年的12月份做值;当传入月份是12时,年份就要加1,也就是来年的1月份值。
第二步
月份也需要定义三个变量保存,当传入的值为7时,第一个变量保存6,第二个变量保存7,第三个变量保存8。
第三步
同时日期也定义三个变量,不过这三个变量不是真正的村存储日期,而是存储当前月的最大日期值,比如当前月有28天,那就存28,如果是30天,那就存30,共有四种情况,分别是28、29、30和31,这些数据用来创建当月的完整日期。
第四步
定义moth月份数组,数组中存放的是1到12月,每个月都是31天的月份序号。
第五步
定义days箭头函数用来判断2月份,因为2月有平年与闰年之分,需要通过特定的手段处理。
第六步
定义dayss箭头函数用来判断30天和31天的月份,配合第四步的moth数组来判定。
第七步
处理当前月为1或12时的年份值和上月值或下月值。
第八步
根据月份获取当月最大天数,首先判断是否是2月。
第九步
到上面的第八步时,相邻3个月的年份、月份和月份最大天数都已经准备好,接下来便是获取对应月份的所有天数值了。
定义名为creationDate的函数,函数的作用是使用for循环生成当月天数。函数参数分别是y、m和d,y表示年份,m表示月份,d表示循环结束条件。这一步需要npm插件辅助,这个插件可以实现阳历和农历之间的相互转换。
第十步
经过第九步之后,我们便拿到了相邻3个月的所有日期值,里面包括阳历、农历和星期等相关值,把3个月的日期值分别存到3个变量中待用。
第十一步
这一步处理星期显示的数据,掐头去尾。定义len2保存当前月的日期长度,获取当前日期数组第一项和最后一项的星期值,并保存到2个变量中。
第十二步
nWeek1 === 7 ? 0 : arr2[0].nWeek当星期等于7时不需要从上个月获取数据补充,否则需要获取上个对应的数据补齐一个星期,也就是需要让数据从星期日开始补齐,当星期值为7时说明当前月的1号正好是星期日。
nWeek3 === 6 ? 0 : nWeek3 === 7 ? nWeek3 - 1 : 6 - nWeek3当前月结束时需要补齐的数据值,如果当前月最后一天正好是星期六,那么就不需要截取下个月的数据来补齐一个星期;如果当前月最后一天是星期日,那么需要从下个月取6天来补全当月数据;如果是其他星期值,那么就需要使用6减去当前星期值。这一步可能会有点晦涩难懂,希望我的解释能帮到你。
第十三步
第十二步我们已经拿到掐头去尾的准确数据,那么我们开始实现掐头去尾的工作吧!掐头会比较麻烦一点,因为需要从数组的末尾开始截取数据,所以i的初始值是数组长度减1,并且i做减减操作,退出循环条件是第十二步中获取的nWeek1值,循环退出条件是nWeek1--到-1,使用unshift向数组前面添加数据。去尾简单一点,直接循环加加就好,这里使用push向数组末尾添加数据。至此日历数据模板已创建完成,把最终数据返回即可。
3、关于其他函数不做解析,基本都是渲染相关操作啦!
4、html不做解释,自行阅读即可。
5、style不做解释,自行阅读即可。
style
body {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
}
.box {
display: flex;
flex-direction: column;
justify-content: center;
}
.item {
background-color: rgba(255, 165, 0, .1);
padding: 2px 0;
border-radius: 3px;
}
.south {
font-size: 18px;
font-weight: 700;
}
.lunar {
font-size: 16px;
}
.week {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px 60px 60px;
text-align: center;
grid-column-gap: 10px;
font-weight: 800;
}
.calendar_box {
margin-top: 6px;
}
.calendar {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px 60px 60px;
text-align: center;
grid-row-gap: 30px;
grid-column-gap: 10px;
}
.y_m_box {
position: fixed;
left: 50%;
top: 10px;
transform: translate(-50%, 0);
display: flex;
flex-direction: column;
align-items: center;
}
.y_btn_box {
display: grid;
grid-template-columns: 68px 68px 68px 68px 68px 68px 68px 68px 68px;
grid-column-gap: 20px;
grid-row-gap: 20px;
}
.m_btn_box {
width: 600px;
margin-top: 26px;
display: flex;
justify-content: space-between;
}
.y_item,
.m_item {
text-align: center;
background-color: rgba(0, 0, 255, .3);
cursor: pointer;
font-weight: 700;
border-radius: 4px;
padding: 2px 0;
box-sizing: border-box;
}
.y_item {
font-size: 16px;
}
.m_item {
width: 36px;
font-size: 18px;
}
.show_box {
margin-top: 10px;
font-size: 30px;
font-weight: 900;
}



















