

二、date.js
(function() { // 为了防止模块编写的时候污染外部环境,就会用匿名函数。
let datepicker = {};
datepicker.getMonthData = function(year, month) {
let ret = [];
if (!year && !month && month !==0) {
let today = new Date();
year = today.getFullYear();
month = today.getMonth() + 1;
}
let firstDay = new Date(year, month - 1, 1);
let firstDayWeekDay = firstDay.getDay();
if (firstDayWeekDay === 0) {
firstDayWeekDay = 7;
}
year = firstDay.getFullYear(); // 哪年
month = firstDay.getMonth() + 1; // 哪月
let lastDayOfLastMoth = new Date(year, month - 1, 0); // 上个月最后一天
let lastDateOfLastMonth = lastDayOfLastMoth.getDate(); // 上个月最后一天是几号
let preMonthDayCount = firstDayWeekDay - 1; // 上个月最后一天是星期几
let lastDay = new Date(year, month, 0); // 这个月最后一天
let lastDate = lastDay.getDate(); // 这个月最后一天是几号
for (let i = 0; i < 7*6; i++) {
let date = i - preMonthDayCount + 1; // 距离上个月最后一天多长时间(单位:天)
let showDate = date;
let 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;
// }
thisMonth = thisMonth === 0 ? 12 :thisMonth === 13 ? 1 : thisMonth;
ret.push({
month: thisMonth,
date: date,
showDate: showDate
});
}
return {
year: year,
month: month,
days: ret
};
};
window.datePicker = datepicker;
})();三、main.js
(function() {
let datePicker = window.datePicker;
let monthData;
let $wrapper;
datePicker.buildUi = function(year, month) {
monthData = datePicker.getMonthData(year, month);
let html = '<div class="ui-datepicker-head">'+
'<a class="ui-datepicker-btn ui-datepicker-prev-btn"><</a>'+
' <a 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 (let i = 0; i < monthData.days.length; i++) {
let 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) {
let year,month;
if (monthData) {
year = monthData.year;
month = monthData.month;
}
if (direction === 'prev') {
month--;
}
if (direction === 'next') {
month++;
}
let html = datePicker.buildUi(year, month);
$wrapper = document.querySelector('.ui-datepicker-wrapper');
if (!$wrapper) {
$wrapper = document.createElement('div');
document.body.appendChild($wrapper);
$wrapper.className = 'ui-datepicker-wrapper';
}
$wrapper.innerHTML = html;
};
datePicker.init = function($dom) {
datePicker.render();
let $input = document.querySelector($dom);
let isOpen = false;
// $dom点击后,日历显示出来,日历位置适应。
$input.addEventListener('click', function() {
if (isOpen) {
$wrapper.classList.remove('ui-datepicker-wrapper-show');
isOpen = false;
} else {
$wrapper.classList.add('ui-datepicker-wrapper-show');
let left = $input.offsetLeft;
let top = $input.offsetTop;
let height = $input.offsetHeight;
$wrapper.style.top = top + height + 2 + 'px';
$wrapper.style.left = left + 'px';
isOpen = true;
}
}, false);
// $wrapper.querySelector('.ui-datepicker-btn').addEventListener();
// 每次渲染完重新绑定事件
// 为不变的元素绑定事件
$wrapper.addEventListener('click', function(e) {
let $target = e.target;
// let containsBtn = $target.classList.contains('ui-datepicker-btn');
if (!$target.classList.contains('ui-datepicker-btn')) {
return;
}
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) {
let $target = e.target;
if ($target.tagName.toLowerCase() !== 'td') {
return;
}
let date = new Date(monthData.year, monthData.month - 1, $target.dataset.date);
$input.value = format(date);
$wrapper.classList.remove('ui-datepicker-wrapper-show');
isOpen = false;
})
}
function format(date) {
let ret = '';
let shuffle = function(num) {
if (num <= 9) {
return `0${num}`;
}
return num;
};
ret += date.getFullYear() + '-';
ret += shuffle(date.getMonth() + 1) + '-';
ret += shuffle(date.getDate());
return ret;
}
})();
一、优化方向:
1、如何在移动端使用这个组件。
2、页面定位比较复杂时,如何处理弹出框的位置。
3、如何让上一个月,下一个月,使用不同的样式。
4、如何让某些日期可点,某些日期不可点。