慕课网课程网址:DatePicker组件开发
<!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>
<style>
.calendar {
width: 240px;
/* font-size: 16px; */
color: #666;
box-shadow: 2px 2px 8px 2px rgba(128, 128, 128, 0.3);
display: none;
position: absolute;
}
.calendar-show {
display: block;
}
.calendar .calendar-header {
padding: 0 20px;
height: 40px;
line-height: 40px;
background: #eee;
text-align: center;
font-weight: bold;
}
.calendar .btn {
text-decoration: none;
font-size: 20px;
color: indianred;
width: 20px;
height: 40px;
line-height: 40px;
}
.calendar .btn-prev {
float: left;
}
.calendar .btn-next {
float: right;
}
.calendar .calendar-body table {
width: 100%;
border-collapse: collapse;
text-align: center;
}
.calendar .calendar-body table thead {
height: 40px;
line-height: 40px;
font-size: 14px;
}
.calendar .calendar-body table td {
height: 30px;
border: 1px solid #f0f0f0;
font-size: 12px;
cursor: pointer;
}
#datepicker {
border: 1px solid #ccc;
border-radius: 4px;
width: 240px;
height: 24px;
line-height: 24px;
}
#datepicker:focus {
outline: 0 none;
border: 1px solid #1abc9c;
}
</style>
</head>
<body>
<input type="text" id="datepicker">
<script>
(function() {
var datepicker = {};
// 获取一个月的每一天数据
datepicker.getMonthData = 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();
// 一个月可能有4-6周,按6周计算
for (var i = 0; i < 7 * 6; i++) {
// date记录当月当天的月日期
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
};
};
var monthData;
var divDom;
datepicker.buildUi = function(year, month) {
monthData = datepicker.getMonthData(year, month);
var html = '<div class="calendar-header">' +
'<a href="#" class="btn btn-prev"><</a>' +
'<span>' + monthData.year + '-' + monthData.month + '</span>' +
'<a href="#" class="btn btn-next">></a>' +
'</div>' +
'<div class="calendar-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++;
// 创建日历,这里要判断如果日历已经存在的话就不用创建了,不然永远只显示当前年月的日期了
divDom = document.querySelector('.calendar');
if (!divDom) {
divDom = document.createElement('div');
divDom.className = 'calendar';
document.body.appendChild(divDom);
}
divDom.innerHTML = datepicker.buildUi(year, month);
}
datepicker.init = function(input) {
datepicker.render();
// 给输入框绑定事件,如果点击就显示或隐藏日历
var $input = document.querySelector(input);
var isOpen = false;
$input.addEventListener('click', function() {
if (isOpen) {
divDom.classList.remove('calendar-show');
isOpen = false;
} else {
divDom.classList.add('calendar-show');
var left = $input.offsetLeft;
var top = $input.offsetTop;
var height = $input.offsetHeight;
divDom.style.left = left + 'px';
divDom.style.top = top + height + 2 + 'px';
isOpen = true;
}
}, false);
// 给左右按钮绑定单击事件,由于init方法只调用一次,而按钮每次都要重新渲染,所以如果直接绑定在按钮上会无效,因为按钮一直在销毁和重建,这里用事件代理
divDom.addEventListener('click', function(e) {
var target = e.target;
if (!target.classList.contains('btn')) {
return;
}
if (target.classList.contains('btn-prev')) {
datepicker.render('prev');
}
if (target.classList.contains('btn-next')) {
datepicker.render('next');
}
}, false);
// 给每个日期绑定单击事件
divDom.addEventListener('click', function(e) {
var target = e.target;
if (target.tagName.toLowerCase() !== 'td') {
return;
}
var date = new Date(monthData.year, monthData.month - 1, target.dataset.date);
$input.value = format(date);
// 点击之后隐藏日历
divDom.classList.remove('calendar-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;
}
// 全局注册一下
window.datepicker = datepicker;
})();
datepicker.init('#datepicker');
</script>
</body>
</html>