index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>datepicker</title>
<link rel="stylesheet" type="text/css" href="./style.css">
<style>
.datepicker {
border:1px solid #ccc;
border-radius: 4px;
padding:5px;
height:24px;
line-height: 24px;
width:230px;
}
.datepicker:focus{
outline: 0 none;
border: 1px solid #1abc9c;
}
</style>
</head>
<body>
<!--<div>-->
<!--前置知识<br>-->
<!--日期对象: new Date(year, month-1, date);<br>-->
<!--new Date(2017,11,1);----- 2017年12月1日<br>-->
<!--越界自动进(退)位<br>-->
<!--getFullYear(0/getMonth()/getDate()<br>-->
<!--getYear():是当前年距离1900年多少年<br>-->
<!--getDay():当天是周几<br>-->
<!--<br><br>-->
<!--当月第一天 new Date(year,month-1,1)<br>-->
<!--当月最后一天 new Date(year,month-1,0) 每个月的最后一天是不固定的,所以这个还蛮好用的<br>-->
<!--12月最后一天:new Date(2016,12,0)<br>-->
<!--星期一~星期天[1,2,3,4,5,6,0]-->
<!--<br><br>-->
<!--</div>-->
<input type="text" class="datepicker"/>
<!--<div class="ui-datepicker-wrapper"></div>-->
<script type="text/javascript" src="datetest.js"></script>
<script type="text/javascript" src="main.js"></script>
<script>
// var monthdate = datepiker.getMonthData(2017,12);
// console.log(monthdate);
// var oDiv = document.querySelector('.ui-datepicker-wrapper');
datepiker.init('.datepicker');
</script>
</body>
</html>
datetest.js
//为了不污染,写在匿名函数中
(function (){
var datepicker = {};
datepicker.getMonthData = function(year,month){
var ret = [];//数组返回结果,每个元素都是当前月份的日期
if((!year || !month) && month != 0){//如果没有 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++){//极端情况是有6周,所以用六周吧
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.datepiker = datepicker;//绑定到window中,暴露这个对象
})();
main.js
(function (){
var datepicker = window.datepiker;
var monthDate;
var $wrapper;
datepicker.buildUi = function(year, month){//渲染函数
monthDate = datepicker.getMonthData(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="ui-datepicker-curr-month">'+monthDate.year+'-'+monthDate.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 < monthDate.days.length; i++){
var date = monthDate.days[i];
if(i % 7 === 0){
html += '<tr>';
}
html += '<td data-data="'+ 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(monthDate){
year = monthDate.year;
month = monthDate.month;
}
if(direction === 'prev') month--;
if(direction === 'next') month++;
var html = datepicker.buildUi(year,month);
// <div class="ui-datepicker-wrapper"></div> 要创建div元素
//
$wrapper = document.querySelector('.ui-datepicker-wrapper');
if(!$wrapper){
$wrapper = document.createElement('div');
document.body.appendChild($wrapper);
$wrapper.className = 'ui-datepicker-wrapper';
}
$wrapper.innerHTML = html;
};
function format(date){
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;
}
datepicker.init = function(input){
datepicker.render();
var $input = document.querySelector(input);//querySelector查找的是第一个class元素
var isOpen = false;
$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.left = left + 'px';
$wrapper.style.top = top + height + 'px';
isOpen = true;
}
},false);
$wrapper.addEventListener('click',function(e){
var $target = e.target;
if(!$target.classList.contains('ui-datepicker-btn'))return;
if($target.classList.contains('ui-datepicker-next-btn')){
datepicker.render("next");
}
if($target.classList.contains('ui-datepicker-prev-btn')){
datepicker.render("prev");
}
},false);//在最外层设置监听事件
$wrapper.addEventListener('click',function(e){
var $target = e.target;
if($target.tagName.toLocaleLowerCase() !== 'td') return;
var date = new Date(monthDate.year,monthDate.month - 1,$target.dataset.data);
$input.value = format(date);
$wrapper.classList.remove('ui-datepicker-wrapper-show');
isOpen = false;
},false);
};
})();