写了一个日历,只使用了(HTML,CSS和JavaScript)实现。用最原生的方式实现一个日历。
日历效果如下:
1. HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>我的日历</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<!-- 日历容器 -->
<div class="calendar">
<!-- 日历头部 -->
<div id="head">
<!-- 当前时间 -->
<div class="currentTime"></div>
<!-- 年份区域 -->
<div class="yearArea">
<button><</button>
<select></select>
<button>></button>
</div>
<!-- 月份区域 -->
<div class="monthArea">
<button><</button>
<select></select>
<button>></button>
</div>
<!-- 今天区域 -->
<div class="todayArea">
<button>今天</button>
</div>
</div>
<!-- 日历中部 -->
<div id="body">
<!-- 星期区域 -->
<div class="weekArea">
<div>一</div>
<div>二</div>
<div>三</div>
<div>四</div>
<div>五</div>
<div style="color: red;">六</div>
<div style="color: red;">日</div>
</div>
<!-- 日期区域 -->
<div class="dateArea"></div>
</div>
<!-- 日历底部 -->
<div id="foot">
<div class="ring">
<button>上一首</button>
<video src="music/01.mp3" width="350px" height="40px" controls autoplay></video>
<button>下一首</button>
</div>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
2. CSS
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
/* ------------------------------------------------日历容器------------------------------------------------ */
.calendar {
width: 100%;
height: 100%;
min-width: 830px;
display: flex;
flex-direction: column;
}
/* ------------------------------------------------日历头部------------------------------------------------ */
.calendar>#head {
height: 120px;
font-size: 24px;
background-color: #87CEEB;
display: flex;
justify-content: center;
align-items: center;
}
/* 当前时间,年份区域,月份区域 */
.calendar>#head>.currentTime,
.calendar>#head>.yearArea,
.calendar>#head>.monthArea {
display: flex;
margin-right: 12px;
}
.calendar>#head>.currentTime {
color: #ff6319;
}
/* 上年,下年,上月,下月,今天 */
.calendar>#head>.yearArea button:nth-of-type(1),
.calendar>#head>.yearArea button:nth-of-type(2),
.calendar>#head>.monthArea button:nth-of-type(1),
.calendar>#head>.monthArea button:nth-of-type(2),
.calendar>#head>.todayArea button {
min-width: 40px;
height: 50px;
font-size: 1em;
}
/* 年份选择框,月份选择框 */
.calendar>#head>.yearArea select,
.calendar>#head>.monthArea select {
min-width: 100px;
height: 50px;
font-size: 1em;
text-align: center;
outline: none;
}
/* ------------------------------------------------日历中部------------------------------------------------ */
.calendar>#body {
flex-grow: 1;
background-color: #d0d2d3;
padding: 0 80px 50px;
}
/* 星期区域 */
.calendar>#body>.weekArea {
display: grid;
grid-template-columns: repeat(7,1fr);
gap: 20px;
}
.calendar>#body>.weekArea div {
text-align: center;
font-size: 30px;
height: 80px;
line-height: 80px;
}
/* 日期区域 */
.calendar>#body>.dateArea {
display: grid;
grid-template-columns: repeat(7,1fr);
grid-template-rows: repeat(6,1fr);
gap: 20px;
height: calc(100% - 80px);
}
.calendar>#body>.dateArea div {
display: flex;
justify-content: center;
align-items: center;
border-radius: 12px;
font-size: 36px;
transition: transform 0.5s, box-shadow 0.5s;
}
.calendar>#body>.dateArea div:hover {
transform: translateY(-10px);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.5);
}
/* ------------------------------------------------日历底部------------------------------------------------ */
.calendar>#foot {
height: 100px;
min-height: 50px;
background-color: #8a7967;
display: flex;
justify-content: center;
}
.calendar>#foot>.ring {
width: 500px;
display: flex;
justify-content: space-evenly;
align-items: center;
}
.calendar>#foot>.ring button {
height: 40px;
}
3. JavaScript
// 当前时间dom
let currentTime = document.getElementsByClassName('currentTime')[0];
// 年份区域dom
let yearArea = document.getElementsByClassName('yearArea')[0];
let lastYearBtn = yearArea.querySelectorAll('button')[0]; //上一年按钮
let yearSelect = yearArea.querySelector('select'); //年份下拉框
let nextYearBtn = yearArea.querySelectorAll('button')[1]; //下一年按钮
// 月份区域dom
let monthArea = document.getElementsByClassName('monthArea')[0];
let lastMonthBtn = monthArea.querySelectorAll('button')[0]; //上一月按钮
let monthSelect = monthArea.querySelector('select'); //月份下拉框
let nextMonthBtn = monthArea.querySelectorAll('button')[1]; //下一月按钮
// 今天区域dom
let todayBtn = document.querySelector(".todayArea"); //今天按钮
// 日期区域dom
let dateArea = document.getElementsByClassName('dateArea')[0];
// 音乐区域dom
let ring = document.getElementsByClassName('ring')[0];
let lastOneBtn = ring.querySelectorAll('button')[0]; //上一首按钮
let videoPlayer = ring.querySelector('video'); //video元素
let nextOneBtn = ring.querySelectorAll('button')[1]; //下一首按钮
// 创建年份列表
for(let i=0;i<200;i++) {
let y = 1900;
let option = document.createElement('option');
option.value = y+i;
option.innerHTML = y+i + '年';
yearSelect.append(option);
}
// 创建月份列表
for(let i=1;i<=12;i++) {
let option = document.createElement('option');
option.value = i;
option.innerHTML = i + '月';
monthSelect.append(option);
}
// 绑定点击事件(上一年按钮)
lastYearBtn.addEventListener('click',function() {
clickYear(1);
})
// 绑定点击事件(下一年按钮)
nextYearBtn.addEventListener('click',function() {
clickYear(2);
})
// 绑定点击事件(上一月按钮)
lastMonthBtn.addEventListener('click',function() {
clickMonth(1);
})
// 绑定点击事件(下一月按钮)
nextMonthBtn.addEventListener('click',function() {
clickMonth(2);
})
// 绑定改变事件(年份下拉框)
yearSelect.addEventListener('change',function(e) {
changeYear(e.target.value);
})
// 绑定改变事件(月份下拉框)
monthSelect.addEventListener('change',function(e) {
changeMonth(e.target.value);
})
// 绑定点击事件(今天按钮)
todayBtn.addEventListener('click',function() {
init();
})
// 绑定点击事件(上一首按钮)
lastOneBtn.addEventListener('click',function() {
let musicNo = videoPlayer.src.slice(-6,-4);
if(musicNo<2) {
alert('已经是第一首啦~');
} else {
videoPlayer.src = videoPlayer.src.replace(musicNo,'0'+(musicNo-1));
}
})
// 绑定点击事件(下一首按钮)
nextOneBtn.addEventListener('click',function() {
let musicNo = videoPlayer.src.slice(-6,-4);
if(musicNo>5) {
alert('已经是最后一首啦~');
} else {
videoPlayer.src = videoPlayer.src.replace(musicNo,'0'+(musicNo*1+1));
}
})
/************************************ 点击上下年按钮 ************************************/
function clickYear(type) {
let y,m;
for(let it of yearSelect.querySelectorAll('option')) {
if(it.selected) {
if(type == 1) {
y = it.value > 1900 ? it.value - 1 : it.value;
} else {
y = it.value < 2099 ? it.value*1 + 1 : it.value;
}
}
}
for(let it of monthSelect.querySelectorAll('option')) {
if(it.selected) {
m = it.value;
}
}
init(`${y}-${m}`);
}
/************************************ 点击上下月按钮 ************************************/
function clickMonth(type) {
let y,m;
for(let it of yearSelect.querySelectorAll('option')) {
if(it.selected) {
y = it.value;
}
}
for(let it of monthSelect.querySelectorAll('option')) {
if(it.selected) {
if(type == 1) {
m = it.value > 1 ? it.value - 1 : it.value;
} else {
m = it.value < 12 ? it.value*1 + 1 : it.value;
}
}
}
init(`${y}-${m}`);
}
/************************************ 改变年份触发 ************************************/
function changeYear(val) {
let m;
for(let it of monthSelect.querySelectorAll('option')) {
if(it.selected) {
m = it.value;
}
}
init(`${val}-${m}`);
}
/************************************ 改变月份触发 ************************************/
function changeMonth(val) {
let y;
for(let it of yearSelect.querySelectorAll('option')) {
if(it.selected) {
y = it.value;
}
}
init(`${y}-${val}`);
}
/************************************ 初始化数据(年份,月份,日期等) ************************************/
function init(appoint) {
let t = appoint===undefined ? new Date() : new Date(appoint);
let year = t.getFullYear();
let month = t.getMonth()+1;
// 年份选择框默认值(当前年份)
for(let it of yearSelect.querySelectorAll('option')) {
if(it.value==year) {
it.selected = "selected";
}
}
// 月份选择框默认值(当前月份)
for(let it of monthSelect.querySelectorAll('option')) {
if(it.value==month) {
it.selected = "selected";
}
}
// 当前月份共有多少天
let currentMonthDays;
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) {
currentMonthDays = 31;
} else if(month==4||month==6||month==9||month==11) {
currentMonthDays = 30;
} else {
if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
currentMonthDays = 29;//闰年二月
} else {
currentMonthDays = 28;//平年二月
}
}
// 创建日期列表
dateArea.innerHTML = "";
for(let i=0;i<42;i++) {
dateArea.append(document.createElement('div'));
}
// 当前月份的1号是星期几(然后从第一个星期的星期几开始往后排列1号,2号,3号...)
let weekIndex = new Date(`${year}-${month}-01`).getDay(); // 星期几的下标
let dateArr = dateArea.children; // 日期的所有格子(6*7)
let dayNum = 1; // 月份1号开始递增的具体日期号(1-31号)
// 给当前月份的日期加入具体内容
for(let i=0;i<dateArr.length;i++) {
if(weekIndex>0) {
if(i>=weekIndex-1 && currentMonthDays>0) {
inFn(i);
}
} else {
if(i>=6 && currentMonthDays>0) {
inFn(i);
}
}
}
function inFn(i) {
let t = new Date();
let ymStr = t.getFullYear() + "-" + (t.getMonth()+1);
let today = t.getDate();//今天几号
dateArr[i].style.backgroundColor = today==dayNum && (year+"-"+month==ymStr) ? "pink" : "#56a0d3";
dateArr[i].value = dayNum;
dateArr[i].innerHTML = dayNum;
dayNum++;
currentMonthDays--;
}
// 将没有日期内容的格子阴影效果去除
for(let it of dateArr) {
if(!it.value) {
it.style.boxShadow = "none";
}
}
}
/************************************ 获取当前时间 ************************************/
function getCurrentTime() {
let t = new Date();
let year = t.getFullYear();
let month = t.getMonth()+1 > 9 ? t.getMonth()+1 : "0"+(t.getMonth()+1);
let date = t.getDate() > 9 ? t.getDate() : "0"+t.getDate();
let hour = t.getHours() > 9 ? t.getHours() : "0"+t.getHours();
let minute = t.getMinutes() > 9 ? t.getMinutes() : "0"+t.getMinutes();
let second = t.getSeconds() > 9 ? t.getSeconds() : "0"+t.getSeconds();
let weeks = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
let week = weeks[t.getDay()];
return year + "年" + month + "月" + date + "日 " + hour + ":" + minute + ":" + second + " " + week;
}
// ------------执行程序------------
init();
currentTime.innerHTML = getCurrentTime();
setInterval(() => {
currentTime.innerHTML = getCurrentTime();
}, 1000);