移动端原生js日历(仅供个人学习用)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>签到日历</title>
<link rel="stylesheet" href="./css/calendar.css">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="./js/calendar.js"></script>
</head>
<body style="background:#F2F3F7">
<header class="HeadTit">
<a href="javascript:;" class="GoBack"></a>
我的班主任
</header>
<section class="calendarBox">
<div class="calendarBoxCont">
<div id="calendar" class="vueBox">
<div class="plan-finish-calendar ">
<div class="calendar">
<!-- 年份 月份 -->
<ul class="month bottom-line">
<!--点击会触发pickpre函数,重新刷新当前日期 -->
<!-- @click="pickPre(currentYear,currentMonth)" -->
<li class="arrow btnLeft">
<i class="mintuifont mintui-arrowright arrowleft"></i>
</li>
<li class="year-month">
<span id="currentTime">2021年5月</span>
</li>
<!-- @click="pickNext(currentYear,currentMonth)" -->
<li class="arrow btnRight">
<i class="mintuifont mintui-arrowright arrowright"></i>
</li>
</ul>
<!-- 星期 -->
<ul class="weekdays">
<li>日</li>
<li>一</li>
<li>二</li>
<li>三</li>
<li>四</li>
<li>五</li>
<li>六</li>
</ul>
<!-- 日期 -->
<ul class="days bottom-line">
<!-- @click="dayCheck(day)" -->
<li v-for="day in days">
<!--本月已签到日期-->
<span :day="day.day"
:class="['day-li',day.isChecked?'day-checked':'']">
<span
:class="['day-span',day.isSign?'day-sign':'',day.day.getMonth()+1
!== currentMonth?'other':'',day.isSigned?'day-signed':'']"
v-text="day.day.getDate()"></span>
</span>
</li>
</ul>
</div>
<div class="plan-calendar-info" >
</div>
</div>
</div>
</div>
</section>
</body>
</html>
js
$(document).ready(() => {
// 初始化数据
var currentDay = 1, // 当前天
currentMonth = 1, // 当前月
currentYear = 1970,
currentWeek = 0, // 一号所在的星期
days = [], // 当月所有天数
content = {},
sign_days = [], // 签到日期
is_sign = false,
currentPlan = {};
// 初始化方法
getSign();
// 获取签到日期
function getSign() {
// 模拟数据
var signDays = [
{
day: "2021/5/19",
is_sign: 1,
},
{
day: "2021/5/20",
is_sign: 1,
},
{
day: "2021/5/23",
is_sign: 1,
},
{
day: "2021/6/24",
is_sign: 1,
},
{
day: "2021/5/27",
is_sign: 1,
},
{
day: "2021/6/13",
is_sign: 1,
},
];
sign_days = signDays;
initData(null);
}
// 判断是否为今天
function isToday(str){
var d = new Date();
var y = d.getFullYear(); // 年
var m = d.getMonth() + 1; // 月份从0开始的
var d = d.getDate(); //日
return str == (y + '-' + m + '-' + d);
}
// 初始化
function initData(cur) {
var date;
if (cur) {
// 切换上一月、下一月
date = new Date(cur);
} else {
var now = new Date(); // 此处取本机时间,应改为服务器时间
var d = new Date(formatDate(now.getFullYear(), now.getMonth() + 1, 1));
d.setDate(35); // 设置天数为35天(32~59都可以,既设置到下一个月的某一天)
date = new Date(formatDate(d.getFullYear(), d.getMonth(), 1));
}
currentDay = new Date().getDate(); // 今日日期 几号
currentYear = date.getFullYear(); // 当前年份
currentMonth = date.getMonth() + 1; // 当前月份
currentWeek = date.getDay(); // 当前月1号是星期几? 0表示星期天
$('.calendar #currentTime').text(currentYear+'年'+currentMonth+'月')
// 当前月最后一天是星期几? 0表示星期天
nextWeek = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDay();
var str = formatDate(currentYear, currentMonth, 1); // 2021/05/01
var nextStr = new Date(
date.getFullYear(),
date.getMonth() + 1,
0
).toLocaleDateString(); // 2021/05/31
days = []; // 初始化日期
// 设置上一个月 需显示 的最后几天 铺满一周
for (var i = currentWeek; i > 0; i--) {
var d = new Date(str);
d.setDate(d.getDate() - i);
var tod=d.getFullYear()+"-" + (d.getMonth()+1) + "-" + d.getDate(); //获取完整日期
var dayobject = {
day: d.getDate(),
isThisMonth:d.getMonth()+1==currentMonth?true:false,
isToDay:isToday(tod),
isSign: isVerDate(d),
isSigned: isSigned(d),
}; // 用一个对象包装Date对象 以便为以后预定功能添加属性
days.push(dayobject); // 将日期放入data 中的days数组 供页面渲染使用
}
// 显示当前月的天数 第二个循环为 j<= 36- currentWeek,
// 因为1号是星期六的时候当前月需显示6行,如2020年8月
num = 0; //第几个月 每遇到1号加1
for (var j = 0; j <= 36 - currentWeek; j++) {
var d = new Date(str);
d.setDate(d.getDate() + j);
var tod=d.getFullYear()+"-" + (d.getMonth()+1) + "-" + d.getDate(); //获取完整日期
var dddd = d.getDate();
var dayobject = {
day: d.getDate(),
isThisMonth:d.getMonth()+1==currentMonth?true:false,
isToDay:isToday(tod),
isSign: isVerDate(d),
isSigned: isSigned(d),
};
if (dddd == 1) {
num++;
}
if (num == 2) {
break;
}
days.push(dayobject);
}
// console.log('当前月1号是星期' + this.currentWeek)
// console.log('当前月最后一天是星期' + this.nextWeek)
// 设置下一个月 需显示 的最前几天铺满一周
for (var k = 1; k <= 6 - nextWeek; k++) {
var d = new Date(nextStr);
d.setDate(d.getDate() + k);
var tod=d.getFullYear()+"-" + (d.getMonth()+1) + "-" + d.getDate(); //获取完整日期
var dayobject = {
day: d.getDate(),
isThisMonth:d.getMonth()+1==currentMonth?true:false,
isToDay:isToday(tod),
isSign: isVerDate(d),
isSigned: isSigned(d),
}; // 用一个对象包装Date对象 以便为以后预定功能添加属性
days.push(dayobject); // 将日期放入data 中的days数组 供页面渲染使用
}
// 调用渲染日历方法
render(days);
}
// 渲染日历内容
function render(dateList) {
let str = "";
let a='';
let newData = JSON.parse(JSON.stringify(dateList));
let aaaa = JSON.parse(JSON.stringify(dateList));
$('body .calendar .days').html(str);
for (let i = 0,len=newData.length/7; i < len; i++) {
str += '<li>';
for (let j = 0; j < 7; j++) {
a=aaaa.shift();
var ss=''
// 选中状态是 class=day-sign
if(a.isToDay){
ss='<span class="day-li " data-Obj='+JSON.stringify(newData.shift())+'><span class="day-span day-today">今</span></span>';
}else{
if(a.isThisMonth){
if(a.isSigned){
ss='<span class="day-li " data-Obj='+JSON.stringify(newData.shift())+'><span class="day-span day-signed">'+a.day+'</span></span>';
} else{
ss='<span class="day-li " data-Obj='+JSON.stringify(newData.shift())+'><span class="day-span">'+a.day+'</span></span>';
}
}else{
ss='<span class="day-li " data-Obj='+JSON.stringify(newData.shift())+'><span class="day-span other">'+a.day+'</span></span>';
}
}
str +=ss;
if (j === 6) {
str += '</li>';
}
}
}
$('body .calendar .days').html(str);
}
// 判断该日期是否有任务
function isVerDate(d) {
var signdays = [];
for (var i in sign_days) {
signdays.push(sign_days[i].day);
}
return signdays.includes(d.toLocaleDateString());
}
// 判断该日期是否有任务
function isSigned(d) {
var signdays = [];
for (var i in sign_days) {
if (sign_days[i].is_sign) {
signdays.push(sign_days[i].day);
}
}
return signdays.includes(d.toLocaleDateString());
}
// 上一月 (@param year, @param month)
function pickPre(year, month) {
var d = new Date(formatDate(year, month, 1));
d.setDate(0);
initData(formatDate(d.getFullYear(), d.getMonth() + 1, 1));
}
// 下一个月 (@param year, @param month)
function pickNext(year, month) {
var d = new Date(formatDate(year, month, 1));
d.setDate(35);
initData(formatDate(d.getFullYear(), d.getMonth() + 1, 1));
}
// 返回 类似 2020/01/01 格式的字符串 ok
function formatDate(year, month, day) {
month < 10 && (month = "0" + month);
day < 10 && (day = "0" + day);
return year + "/" + month + "/" + day;
}
// 点击日期查询
function dayCheck(day) {
var currentPlan = {
title: "",
date: "",
list: [],
};
currentPlan.date =
day.day.toLocaleDateString().split("/")[1] +
"月" +
day.day.toLocaleDateString().split("/")[2] +
"日";
for (var i in this.days) {
this.$set(this.days[i], "isChecked", 0);
}
this.$set(day, "isChecked", 1);
if (day.isSign) {
if (day.isSigned) {
currentPlan.list = [
{
name: "重做计划1",
},
{
name: "重做计划2",
},
{
name: "重做计划3",
},
{
name: "重做计划4",
},
{
name: "重做计划5",
},
{
name: "重做计划6",
},
{
name: "重做计划7",
},
{
name: "重做计划8",
},
];
currentPlan.title = "已完成计划×" + currentPlan.list.length;
currentPlan.name =
"学习考点:财务成本管理《第一章 财务管理基本管理》财务成本管理";
currentPlan.nums = 100;
} else {
currentPlan.title = "未完成计划";
}
} else {
currentPlan.title = "暂无任务";
}
this.currentPlan = currentPlan;
}
// 为日期切换绑定事件(上一个月)
$('body').on('click','.calendar .btnLeft',function(){
pickPre(currentYear,currentMonth)
})
// 为日期切换绑定事件(下一个月)
$('body').on('click','.calendar .btnRight',function(){
pickNext(currentYear,currentMonth)
})
});
CSS
.calendarBox{padding: .5rem .5rem 0;}
.calendarBoxCont{}
#calendar{position: relative;width: 100%;height: 100%;}
.plan-finish-calendar {
width: 100%;height: 100%;
}
.plan-finish-btns {
width: 100%;
padding: 0.8rem 0.3rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.plan-finish-btns li {
width: 3rem;
height: 0.84rem;
background: rgba(21, 188, 195, 0.11);
border-radius: 0.42rem;
display: flex;
justify-content: center;
align-items: center;
font-size: 0.32rem;
color: #15bcc3;
}
.plan-finish-btns li:last-child {
background: #15bcc3;
color: #fff;
}
/* 日历 */
.calendar {
width: 100%;
background: #fff;
box-shadow: 0px 3px 24px 0px rgba(0, 0, 0, 0.1);
border-radius: 0.5rem;
overflow: hidden;
padding:0 0 0.5rem 0 ;
}
.calendar .month {
background: #ffffff;
padding: 0.3rem;
display: flex;
justify-content: space-between;
align-items: center;
white-space: nowrap;
}
.calendar .month li {
text-transform: uppercase;
letter-spacing: 0;
}
.calendar .month .arrow {
color: #333;
width: 2rem;
font-size: 0.24rem;
display: flex;
justify-content: center;
align-items: center;
}
.calendar .mintui-arrowright {
width: .7rem;
height: .7rem;
border-top: 2px solid #C0C2CA;
border-right: 2px solid #C0C2CA;
margin: .5rem;
transform: rotate(45deg);
}
.calendar .arrowleft {
transform: rotate(-135deg);
}
.calendar .month .year-month {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-size: .8rem;
color: #2d2d2d;
}
.calendar .weekdays {
padding: 0.3rem 0;
/* background-color: rgba(95, 117, 207, 0.2); */
/* border-radius: 0.4rem; */
display: flex;
flex-wrap: wrap;
font-size: .8rem;
justify-content: space-around;
/* margin-bottom: 0.1rem; */
}
.calendar .weekdays li {
display: inline-block;
text-align: center;
}
.calendar .days {
/*日期*/
background: #ffffff;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
padding-bottom: 0.2rem;
}
.calendar .days li {
width: 100%;
box-sizing: border-box;
text-align: center;
color: #000;
display: flex;
justify-content: space-around;
align-items: center;
}
.calendar .days li .day-li {
position: relative;
width: 1.7rem;
height: 1.7rem;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.65rem;
border-radius: 50%;
margin: .15rem 0;
}
.calendar .days li .day-checked {
border: 1px solid #15bcc3;
}
.calendar .days li .day-li .day-span {
position: relative;
width: 1.5rem;
height: 1.5rem;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #fff;
border-radius: 50%;
}
.calendar .other {
color: #ccc;
}
.calendar .day-sign {
/*签到的日期*/
background-color: #f5f5f5;
color: #5F75CF;
}
.calendar .day-today {
background-color: #5F75CF;
color: #fff;
}
.calendar .day-signed {
position: relative;
color: #000;
}
.calendar .day-signed:before {
display: block;
position: absolute;
content: "";
left: 0;
right: 0;
bottom: -.2rem;
width: .3rem;
height: .3rem;
margin: auto;
border-radius: 50%;
background-color: #5F75CF;
color: #000;
}
.plan-calendar-info {
width: 100%;
padding: 0.32rem 0;
}
最终效果如下: