点击选择,DatePicker组件开发教程-慕课网https://www.imooc.com/video/14518分为:
ui,render,事件,日期的操作
源码如下:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" 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 style="margin: 10px; height: 1000px;">
<div>
<div style="margin: 30px;">
<input type="text" class="datepicker">
</div>
</div>
<script src="date.js"></script>
<script src="main.js"></script>
<script>
datepicker.init('.datepicker')
</script>
</body>
</html>
style.css
.ui-datepicker-wrapper{
width: 240px;
font-size: 16px;
color: #666;
box-shadow: 2px 2px 8px 2px rgba(128, 128, 128, .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 #ccc;
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;
}
.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: 49px;
}
.ui-datepicker-wrapper .ui-datepicker-body td{
border: 1px solid #f0f0f0;
font-size: 10px;
cursor: pointer;
}
main.js
(function(){
var datepicker = window.datepicker;
var monthData;
var $wrapper;
datepicker.buildUi = function(year, month){
monthData = 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">'+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);
// $dom.innerHTML=html;
$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.addEventListener('click', function(){
if(isOpen) {
$wrapper.classList.remove('ui-datepicker-wrapper-show')
isOpen=false;
}else{
$wrapper.classList.add('ui-datepicker-wrapper-show')
// 根据input的位置,设置日期的位置
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 ,这样就不会因为重新渲染而失效
$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');
}else if($target.classList.contains('ui-datepicker-prev-btn')){
datepicker.render('prev');
}
}, false);
$wrapper.addEventListener('click', function(e){
var $target = e.target;
if($target.tagName.toLowerCase() !== 'td')return;
// data-开头的数据在dataset里
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;
}
})();
date.js
(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();
for(var i=0; i<7*6; i++){
var date = i - preMonthDayCount + 1; //
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;
})();