js日历demo

最近有个项目需要做一个日历,然后在网上没有找到合适的日历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>

···

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343