В уроке показана реализация квадратного календарика на JavaScript. Разобран общий подход к реализации проектов с помощью пользовательских функций.
Начало
Продложение
Исходники кода
#calendar {
display: inline-block;
}
#calendar td, #calendar th {
padding: 10px;
border: 1px solid black;
text-align: center;
}
#calendar .nav, #calendar .info {
text-align: center;
}
#calendar a {
color: blue;
font-size: 25px;
text-decoration: none;
}
#calendar a:hover {
color: red;
}
#calendar .active {
color: red;
}
<div class="info">Январь 2018</div>
<table>
<thead>
<tr>
<th>пн</th>
<th>вт</th>
<th>ср</th>
<th>чт</th>
<th>пт</th>
<th>сб</th>
<th>вс</th>
</tr>
</thead>
<tbody class="dates"></tbody>
</table>
<div class="nav">
<a href="#" class="prev">←</a>
<a href="#" class="next">→</a>
</div>
(function(selector) {
initCalendar(document.querySelector(selector));
function initCalendar(calendar) {
var date = new Date();
var showedYear = date.getFullYear();
var showedMonth = date.getMonth();
var currentMoment = {
year: showedYear,
month: showedMonth,
date: date.getDate()
};
var dates = calendar.querySelector('.dates');
var info = calendar.querySelector('.info');
drawCalendar(showedYear, showedMonth, currentMoment, calendar);
var prev = calendar.querySelector('.prev');
var next = calendar.querySelector('.next');
prev.addEventListener('click', function() {
showedYear = getPrevYear(showedYear, showedMonth);
showedMonth = getPrevMonth(showedMonth);
drawCalendar(showedYear, showedMonth, currentMoment, calendar);
});
next.addEventListener('click', function() {
showedYear = getNextYear(showedYear, showedMonth);
showedMonth = getNextMonth(showedMonth);
drawCalendar(showedYear, showedMonth, currentMoment, calendar);
});
function drawCalendar(showedYear, showedMonth, currentMoment, calendar) {
drawDates(showedYear, showedMonth, dates);
showInfo(showedYear, showedMonth, info);
showCurrentDate(showedYear, showedMonth, currentMoment, dates);
}
}
function showCurrentDate(showedYear, showedMonth, currentMoment, dates) {
if (
showedYear == currentMoment['year'] &&
showedMonth == currentMoment['month']
) {
var tds = dates.querySelectorAll('td');
for (var i = 0; i < tds.length; i++) {
if (tds[i].innerHTML == currentMoment['date']) {
tds[i].classList.add('active');
break;
}
}
}
}
function getPrevYear(year, month) {
if (month == 0) {
return year - 1;
} else {
return year;
}
}
function getPrevMonth(month) {
if (month == 0) {
return 11;
} else {
return month - 1;
}
}
function getNextYear(year, month) {
if (month == 11) {
return year + 1;
} else {
return year;
}
}
function getNextMonth(month) {
if (month == 11) {
return 0;
} else {
return month + 1;
}
}
function showInfo(year, month, elem) {
elem.innerHTML = getMonthName(month) + ' ' + year;
}
function getMonthName(num) {
var monthes = [
'Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн',
'Июль', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'
];
return monthes[num];
}
function drawDates(year, month, dates) {
var arr = [];
var firstDateOfMonth = 1;
var lastDateOfMonth = getLastDayOfMonth(year, month);
var unshiftElemsNum = getUnshiftElemsNum(year, month);
var pushElemsNum = getPushElemsNum(year, month);
arr = createArr(firstDateOfMonth, lastDateOfMonth);
arr = unshiftElems(unshiftElemsNum, '', arr);
arr = pushElems(pushElemsNum, '', arr);
arr = chunkArr(7, arr);
createTable(arr, dates);
}
//[['', '', 1, 2, 3, 4, 5], [], [], ]
function createTable(arr, parent) {
parent.innerHTML = '';
for (var i = 0; i < arr.length; i++) {
var tr = document.createElement('tr');
for (var j = 0; j < arr[i].length; j++) {
var td = document.createElement('td');
td.innerHTML = arr[i][j];
tr.appendChild(td);
}
parent.appendChild(tr);
}
}
function createArr(from, to) {
var arr = [];
for (var i = from; i <= to; i++) {
arr.push(i);
}
return arr;
}
function unshiftElems(num, elem, arr) {
for (var i = 0; i < num; i++) {
arr.unshift(elem);
}
return arr;
}
function pushElems(num, elem, arr) {
for (var i = 0; i < num; i++) {
arr.push(elem);
}
return arr;
}
function getLastDayOfMonth(year, month) {
var date = new Date(year, month + 1, 0);
return date.getDate();
}
/*
function getLastDayOfMonth(year, month) {
if (month == 1) {
if (isLeap(year)) {
return 29;
} else {
return 28;
}
} else {
var days = [31, undefined, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
return days[month];
}
}
function isLeap(year) {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
return true;
} else {
return false;
}
}
*/
function getUnshiftElemsNum(year, month) {
var jsDayNum = getFirstWeekDayOfMonthNum(year, month);
var realDayNum = getRealDayOfWeekNum(jsDayNum);
return realDayNum - 1;
}
function getPushElemsNum(year, month) {
var jsDayNum = getLastWeekDayOfMonthNum(year, month);
var realDayNum = getRealDayOfWeekNum(jsDayNum);
return 7 - realDayNum;
}
function chunkArr(num, arr) {
var result = [];
var chunk = [];
var iterCount = arr.length / num;
for (var i = 0; i < iterCount; i++) {
chunk = arr.splice(0, num);
result.push(chunk);
}
return result;
}
function getRealDayOfWeekNum(jsNumOfDay) {
if (jsNumOfDay == 0) {
return 7;
} else {
return jsNumOfDay;
}
}
function getFirstWeekDayOfMonthNum(year, month) {
var date = new Date(year, month, 1);
return date.getDay();
}
function getLastWeekDayOfMonthNum(year, month) {
var date = new Date(year, month + 1, 0);
return date.getDay();
}
}('#calendar'));