最近有个项目需要做一个日历,然后在网上没有找到合适的日历demo,索性自己写一个
这个是实现后的样子
demo支持上下月的切换,相关字段都有具体说明
如何判断当前月份1号是星期几
var myDate = new Date(checkedY,checkedM-1,'01');
var afterDay = myDate.getDay(); // 当前月份1号 星期几
checkedY 当前年份
checkedM 当前月份(月份是以0~11返回的所以需要-1);
获取到afterDay 之后需要先循环几个空的数组(如果不循环,每个月的1号都会是星期日或者星期一)
获取当前月份一共有多少天
var d = new Date(checkedY, checkedM, 0);
var remain = d.getDate();
获取到remain之后把当前月份循环并展示出来
如果设计稿中不需要展示前一个月及下一个月的日期那么就大功告成了 (*•̀ᴗ•́*)و ̑̑
如果需要展示那么在第①步获取到当前月份是星期几之后并计算上一个月一共有多少天
tips.在计算上一个月的天数之前需要判断上一个月到底是几月如果上一个月是12月计算之前需要把年份-1;然后把对应的日期塞到数组中;
计算完当前月份之后,需要对下一个月进行计算;先计算当前数组的长度。然后 /7 在parseInt(); 获取到这个值之后 var MaxDay = (week+1)*7 -listArr.length; 得出下一个月在当前月份展示的数量,然后再进行循环就大功告成了 (*•̀ᴗ•́*)و ̑̑
代码:
···
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>日历demo</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style type="text/css">
#app {
width: 100%;
height: 100%;
position: relative;
}
a,
abbr,
acronym,
address,
applet,
article,
aside,
audio,
b,
big,
blockquote,
body,
canvas,
caption,
center,
cite,
code,
dd,
del,
details,
dfn,
div,
dl,
dt,
em,
embed,
fieldset,
figcaption,
figure,
footer,
form,
h1,
h2,
h3,
h4,
h5,
h6,
header,
hgroup,
html,
i,
iframe,
img,
ins,
kbd,
label,
legend,
li,
main,
mark,
menu,
nav,
object,
ol,
output,
p,
pre,
q,
ruby,
s,
samp,
section,
small,
span,
strike,
strong,
sub,
summary,
sup,
table,
tbody,
td,
tfoot,
th,
thead,
time,
tr,
tt,
u,
ul,
var,
video {
margin: 0;
padding: 0;
border: 0;
vertical-align: baseline;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section {
display: block;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:after,
blockquote:before,
q:after,
q:before {
content: "";
content: none;
}
a:active,
a:hover {
outline: none;
}
button:active,
button:hover {
outline: none;
}
button {
outline: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body,
button,
input,
select,
textarea {
font-family: PingFang SC, Helvetica, Heiti SC, Hiragino Sans GB, tahoma, arial, sans-serif;
}
.clearfix:after {
content: "\A0";
display: block;
visibility: hidden;
width: 0;
height: 0;
clear: both;
font-size: 0;
line-height: 0;
overflow: hidden;
}
.clearfix {
zoom: 1;
}
html {
font-size: 100px;
width: 100%;
max-width: 750px;
margin: 0 auto;
}
body {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
-webkit-tap-highlight-color: transparent;
}
@media screen and (min-width: 360px) and (max-width: 374px) {
html {
font-size: 48px;
}
}
@media screen and (min-width: 375px) and (max-width: 383px) {
html {
font-size: 50px;
}
}
@media screen and (min-width: 384px) and (max-width: 399px) {
html {
font-size: 51.2px;
}
}
@media screen and (min-width: 400px) and (max-width: 413px) {
html {
font-size: 53.33px;
}
}
@media screen and (min-width: 414px) and (max-width: 512px) {
html {
font-size: 55.2px;
}
}
@media screen and (min-width: 513px) and (max-width: 649px) {
html {
font-size: 60px;
}
}
@media screen and (max-width: 320px) {
html {
font-size: 42.66px;
}
}
@media screen and (max-device-height: 568px) {
html {
font-size: 42.66px;
}
}
@media screen and (max-device-height: 480px) {
html {
font-size: 38px;
}
}
* {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
input,
textarea {
-webkit-user-select: auto;
margin: 0;
padding: 0;
outline: none;
}
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
position: relative;
}
.PlaneTicket {
width: 100%;
}
.calendar-box {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.3);
}
.calendar-inner {
width: 100%;
height: auto;
background-color: #fff;
}
.calendar {
width: 6.54rem;
margin: auto;
}
.calendar-M {
display: flex;
justify-content: space-between;
padding-top: 0.54rem;
text-align: center;
}
.before-M,
.after-M {
text-align: center;
height: 0.28rem;
width: 0.82rem;
line-height: 1;
padding: 0.14rem 0.2rem;
border: 0.01rem solid rgb(54, 179, 116);
color: rgb(54, 179, 116);
font-size: 0.28rem;
border-radius: 0.28rem;
}
.before-M>.arrow {
width: 0.12rem;
height: 0.2rem;
margin-right: 0.1rem;
}
.after-M>.arrow {
width: 0.12rem;
height: 0.2rem;
margin-left: 0.1rem;
transform: rotateY(180deg);
}
.now-M {
font-size: 0.48rem;
color: rgb(51, 51, 51);
line-height: 0.56rem;
height: 0.56rem;
}
.week {
width: 100%;
display: flex;
justify-content: space-between;
font-size: 0.28rem;
color: rgb(51, 51, 51);
margin-top: 0.96rem;
padding-bottom: 0.15rem;
border-bottom: 0.01rem solid rgb(221, 221, 221);
}
.day-box {
background-color: #fff;
width: 7.42rem;
margin: auto;
font-size: 0.28rem;
color: rgb(51, 51, 51);
display: flex;
justify-content: flex-start;
flex-flow: row wrap;
text-align: center;
margin-top: 0.49rem;
padding-bottom: 0.49rem;
}
.date {
width: 1.06rem;
height: 1.06rem;
border-radius: 1.06rem;
display: block;
line-height: 1.06rem;
}
.before {
color: #ccc;
}
.showOther {
background: linear-gradient(to bottom, rgb(119, 211, 102) 0%, rgb(1, 174, 133) 100%) !important;
color: white;
}
.show {
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<div class="PlaneTicket">
<div class="calendar-box" @click="hide" v-show="calendarShow">
<div class="calendar-inner" @click.stop>
<div class="calendar">
<div class="calendar-M">
<div class="before-M" @click="before">
<span>{{beforeM}}月</span>
</div>
<div class="now-M">{{checkedY}}-{{checkedM}}</div>
<div class="after-M" @click="after">
<span>{{afterM}}月</span>
</div>
</div>
<div class="week">
<span class="week-detail" v-for="(item,index) in weekList" :key="index">{{item.day}}</span>
</div>
</div>
<div class="day-box">
<div class="date" v-for="(item,index) in dataList" @click="getData(item.D_y,item.D_m,item.D_d,item.beforeDay)"
:key="index" :class="{'showOther': item.isClick}">
<span v-if="item.isNow">今日</span>
<span :class="{'before':item.beforeDay}" v-if="!item.isNow">{{item.D_d}}</span>
</div>
</div>
</div>
</div>
<div @click="showCalendar" class="show">显示日历</div>
</div>
<script>
new Vue({
el: '#app',
data: {
weekList: [{
day: '日'
},
{
day: '一'
},
{
day: '二'
},
{
day: '三'
},
{
day: '四'
},
{
day: '五'
},
{
day: '六'
}
],
calendarShow: true,
nowY: '',
nowM: '',
beforeM: '',
afterM: '',
checkedY: '',
checkedM: '',
checkedD: '',
dataList: [],
},
created() {
var nowDate = new Date();
var nowY = nowDate.getFullYear();
var nowM = nowDate.getMonth() + 1;
if (nowM == '12') {
this.beforeM = nowM - 1;
this.afterM = '1';
} else if (nowM == '1') {
this.beforeM = '12';
this.afterM = nowM + 1;
} else {
this.beforeM = nowM - 1;
this.afterM = nowM + 1;
}
if (nowM < 10) {
nowM = '0' + nowM
}
var nowD = nowDate.getDate();
this.nowY = nowY;
this.nowM = nowM;
this.nowD = nowD;
this.checkedY = nowY;
this.checkedM = nowM;
this.checkedD = nowD;
this.getDate();
},
methods: {
showCalendar() {
this.calendarShow = true;
},
before() {
if (this.beforeM == '1') {
this.beforeM = 12;
this.afterM = parseInt(this.checkedM);
this.checkedM = 1;
} else {
this.beforeM = parseInt(this.beforeM) - 1;
if (this.checkedM == '1') {
this.checkedY = parseInt(this.checkedY) - 1;
this.afterM = 1;
this.checkedM = 12;
} else if (this.checkedM == '12') {
this.afterM = 12;
this.checkedM = parseInt(this.checkedM) - 1;
} else {
this.afterM = parseInt(this.checkedM);
this.checkedM = parseInt(this.checkedM) - 1;
}
}
this.getDate();
},
after() {
if (this.afterM == '12') {
this.afterM = 1;
this.checkedM = 12;
this.beforeM = parseInt(this.checkedM) - 1;
} else {
this.afterM = parseInt(this.afterM) + 1;
if (this.checkedM == '12') {
this.checkedY = parseInt(this.checkedY) + 1;
this.beforeM = 12;
this.checkedM = 1;
} else if (this.checkedM == '1') {
this.beforeM = 1;
this.checkedM = parseInt(this.checkedM) + 1;
} else {
this.checkedM = parseInt(this.checkedM) + 1;
this.beforeM = parseInt(this.checkedM) - 1;
}
}
this.getDate();
},
getDate() {
var myDate = new Date(this.checkedY, this.checkedM - 1, '01');
var afterDay = myDate.getDay(); // 当前月份1号 星期几
// 获取上月份一共多少天
var beforeY = '';
var beforeM = '';
beforeY = this.checkedY;
beforeM = this.checkedM - 1;
if (beforeM < 10) {
beforeM = '0' + beforeM;
}
var beforeDate = new Date(beforeY, beforeM, 0);
var beforeDay = beforeDate.getDate();
var listArr = [];
if (afterDay > 0) {
for (var i = 0; i < afterDay; i++) {
var beD_d = beforeDay - afterDay + i + 1;
var now = false;
var day = {
D_y: beforeY, // 当前年份
D_m: beforeM,
D_d: beD_d,
isNow: now,
isChecked: false,
beforeDay: true,
isClick: false,
}
listArr.push(day);
}
}
var d = new Date(this.checkedY, this.checkedM, 0);
var remain = d.getDate();
for (var z = 1; z < remain + 1; z++) {
var now = ''; // 是否是当前日期
var isClick = ''; // 是否是选中状态
if (this.nowY == this.checkedY && this.nowM == this.checkedM && z == this.nowD) {
now = true;
isClick = true;
} else {
now = false;
isClick = false;
}
var beforeDay = ''; // 是否是已经过去的日期
if (this.nowY == this.checkedY && this.nowM == this.checkedM && z < this.nowD || this.nowY == this.checkedY &&
this.nowM > this.checkedM || this.nowY > this.checkedY) {
beforeDay = true;
} else {
beforeDay = false;
}
var day = {
D_y: this.checkedY, // 当前年份
D_m: this.checkedM, // 当前月份
D_d: z, // 当前日期
isNow: now, // 是否是今日
isChecked: false,
beforeDay: beforeDay,
isClick: isClick,
}
listArr.push(day);
}
// 计算后面一个月的时间
var week = parseInt(listArr.length / 7);
var MaxDay = (week + 1) * 7 - listArr.length;
if (MaxDay < 7) {
for (var m = 0; m < MaxDay; m++) {
var afterY = '';
var afterM = '';
if (this.checkedM == 12) {
afterY = this.checkedY + 1;
afterM = 1;
} else {
afterY = this.checkedY;
afterM = this.checkedM + 1;
}
var day = {
D_y: afterY, // 当前年份
D_m: afterM, // 当前月份
D_d: m + 1, // 当前日期
isNow: false, // 是否是今日
isChecked: false,
beforeDay: true,
isClick: false,
}
listArr.push(day);
}
}
console.log('listArr:',listArr);
this.dataList = listArr;
},
getData(Y, M, D, isBefore) {
if (isBefore) {
console.log('禁止点之前的时间')
return false;
} else {
console.log("当前点击的日期为:", Y + '-' + M + '-' + D);
this.checkedY = Y;
this.checkedM = M;
this.checkedD = D;
var dataList = this.dataList;
for (var i = 0; i < dataList.length; i++) {
if (dataList[i].D_d == D && dataList[i].D_m == M) {
dataList[i].isClick = true;
}
else {
dataList[i].isClick = false;
}
}
this.dataList = dataList;
this.ticketList = [];
this.page = 1;
this.hasMore = true;
}
},
hide() {
this.calendarShow = false;
}
}
})
</script>
</body>
</html>
···