经历千辛万苦终于成功做好了一个日历组件了(泪目
直接创建文件,复制粘贴就可以在网页上实现了
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>日期选择器</title>
<link rel="stylesheet" href="style.css">
<style>
.datepicker {
border: 1px solid #ccc;
border-radius: 4px;
width: 230px;
padding: 5px;
line-height: 24px;
}
.datepicker:focus {
outline: none;
border: 1px solid #1abc9c;
}
</style>
</head>
<body>
<input type="text" class="datepicker">
</body>
<script src="./data.js"></script>
<script src="./main.js"></script>
<script>
// var monthDate = datepicker.getMonthDate(2019, 2);
// console.log(monthDate);
// datepicker.init(document.querySelector('.ui-datepicker-wrapper'))
datepicker.init('.datepicker');
</script>
</html>
data.js
(function(){
var datepicker = {};
datepicker.getMonthDate = function (year, month) {
var ret = [];
if(!year || !month){
var today = new Date();
year = today.getFullYear();
month = today.getMonth() + 1;
}
var firstDay = new Date(year, month-1, 1);//获取当月第一天
var firstDayWeekDay = firstDay.getDay();//获取星期几,才好判断排在第几列
if(firstDayWeekDay === 0){//周日
firstDayWeekDay = 7;
}
year = firstDay.getFullYear();
month = firstDay.getMonth() + 1;
var lastDayOfLastMonth = new Date(year, month-1, 0);//获取最后一天
var lastDateOfLastMonth = lastDayOfLastMonth.getDate();
var preMonthDayCount = firstDayWeekDay - 1;
var lastDay = new Date(year, month, 0);
var lastDate = lastDay.getDate();
for(var i=0; i<7*6; i++){
var date = i + 1 - preMonthDayCount;
var showDate = date;
var thisMonth = month;
//上一月
if(date <= 0){
thisMonth = month - 1;
showDate = lastDateOfLastMonth + date;
}else if(date > lastDate){
//下一月
thisMonth = month + 1;
showDate = showDate -lastDate;
}
if(thisMonth === 0){
thisMonth = 12;
}
if(thisMonth === 13){
thisMonth = 1;
}
ret.push({
month: thisMonth,
date: date,
showDate: showDate
})
}
return {
year: year,
month:month,
days: ret
};
}
window.datepicker = datepicker;//该函数唯一暴露的对象
})();
main.js
(function () {
var datepicker = window.datepicker;
var monthData;
var $wrapper;
//渲染函数,由于没有使用第三方插件或库,所以使用的是模板拼接的方法
datepicker.buildUi = function (year, month) {
monthData = datepicker.getMonthDate(year, month);
var html = '<div class="ui-datepicker-header">' +
'<a href="#" class="ui-datepicker-btn ui-datepicker-prev-btn"><</a>' +
'<a href="#" class="ui-datepicker-btn ui-datepicker-next-btn">></a>' +
'<span class="datepicker-curr-month">'+monthData.year+'-'+monthData.month+'</span>' +
'</div>' +
'<div class="ui-datepicker-body">' +
'<table>' +
'<thead>' +
'<tr>' +
'<th>一</th>' +
'<th>二</th>' +
'<th>三</th>' +
'<th>四</th>' +
'<th>五</th>' +
'<th>六</th>' +
'<th>日</th>' +
'</tr>' +
'</thead>' +
'<tbody>';
for (var i = 0; i < monthData.days.length; i++) {
var date = monthData.days[i];
if (i % 7 === 0) {
html += '<tr>';
}
html += '<td data-date="'+date.date+'">' + date.showDate + '</td>';
if (i % 7 === 6) {
html += '</tr>';
}
}
html+='</tbody>' +
'</table>'+
'</div>';
return html;
};
//日历渲染函数
datepicker.render = function (direction) {
var year, month;
if (monthData) {
year = monthData.year;
month = monthData.month;
}
if (direction === 'prev') month--;
if (direction === 'next') month++;
var html = datepicker.buildUi(year,month);
$wrapper=document.querySelector('.ui-datepicker-wrapper');
if(!$wrapper){
$wrapper = document.createElement('div');
$wrapper.className = 'ui-datepicker-wrapper';
}
$wrapper.innerHTML = html;
document.body.appendChild($wrapper);
};
//初始换函数
datepicker.init = function (input) {
datepicker.render();
var $input=document.querySelector(input);
var isOpen=false;
//给input框赋予点击事件
$input.addEventListener('click',function(){
if(isOpen){
$wrapper.classList.remove('ui-datepicker-wrapper-show');
isOpen=false;
}else{
$wrapper.classList.add('ui-datepicker-wrapper-show');
var left=$input.offsetLeft;
var top=$input.offsetTop;
var height=$input.offsetHeight;
$wrapper.style.top=top+height+2+'px';
$wrapper.style.left=left+'px';
isOpen=true;
}
},false);
//给按钮添加点击事件
$wrapper.addEventListener('click',function(e){
var $target=e.target;
if(!$target.classList.contains('ui-datepicker-btn')){
return false;
}
//上一月,下一月
if($target.classList.contains('ui-datepicker-prev-btn')){
datepicker.render('prev');
}else if($target.classList.contains('ui-datepicker-next-btn')){
datepicker.render('next');
}
},false);
$wrapper.addEventListener('click',function(e){
var $target= e.target;
if($target.tagName.toLocaleLowerCase()!=='td'){
return false;
}
var date=new Date(monthData.year,monthData.month-1,$target.dataset.date);
$input.value=format(date);
$wrapper.classList.remove('ui-datepicker-wrapper-show');
isOpen=false;
},false);
};
//格式化数据
function format(date){
var ret='';
var padding=function(num){
if(num<=9){
return '0'+num;
}
return num;
};
ret+=date.getFullYear()+'-';
ret+=padding(date.getMonth()+1)+'-';
ret+=padding(date.getDate());
return ret;
}
})();
style.css
/* 最外层区域 */
.ui-datepicker-wrapper {
width: 240px;
font-size: 16px;
color: #666666;
box-shadow: 2px 2px 8px 2px rgba(128, 128, 128, 0.3);
display: none;
position: absolute;
}
.ui-datepicker-wrapper-show {
display: block;
}
/* 头部区域 */
.ui-datepicker-wrapper .ui-datepicker-header {
padding: 0 20px;
height: 50px;
line-height: 50px;
text-align: center;
background: #f0f0f0;
border-bottom: 1px solid #cccccc;
font-weight: bold;
}
/* 设置两个按钮 */
.ui-datepicker-wrapper .ui-datepicker-btn {
font-family: serif;
font-size: 20px;
width: 20px;
height: 50px;
line-height: 50px;
color: #1abc9c;
text-align: center;
cursor: pointer;
text-decoration: none;
}
.ui-datepicker-wrapper .ui-datepicker-prev-btn {
float: left;
}
.ui-datepicker-wrapper .ui-datepicker-next-btn {
float: right;
}
/* body区域 */
.ui-datepicker-wrapper .ui-datepicker-body table {
width: 100%;
border-collapse: collapse;
}
/* 表头和正文 */
.ui-datepicker-wrapper .ui-datepicker-body th,
.ui-datepicker-wrapper .ui-datepicker-body td {
height: 30px;
text-align: center;
}
.ui-datepicker-wrapper .ui-datepicker-body th {
font-size: 12px;
height: 40px;
line-height: 40px;
}
/* 表格部分 */
.ui-datepicker-wrapper .ui-datepicker-body td {
border: 1px solid #f0f0f0;
font-size: 10px;
width: 14%;
cursor: pointer;
}