Ошибка переключения календаря в JavaScript

Пусть мы хотим сделать стрелки для переключения календаря. В этом случае можно допустить ряд характерных ошибок. Давайте их рассмотрим.

Пусть у нас есть кнопки переключения и элемент, в который мы для простоты будем выводить не календарь, а просто год и название месяца:

<button id="prev">prev</button> <div id="elem"></div> <button id="next">next</button>

Получим ссылки на наши элементы:

let elem = document.querySelector('#elem'); let prev = document.querySelector('#prev'); let next = document.querySelector('#next');

Пусть у нас также есть функция, которая параметром принимает номер месяца и возвращает его название:

function getMonthName(month) { let names = [ 'янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек' ]; return names[month]; }

Давайте по загрузке страницы получим текущий год и месяц:

let date = new Date; let year = date.getFullYear(); let month = date.getMonth();

Выведем в наш элемент год и название месяца (имитация календаря):

elem.textContent = year + ' ' + getMonthName(month);

Давайте теперь на переключатели навесим обработчики кликов:

prev.addEventListener('click', function() { // показываем предыдущий месяц }); next.addEventListener('click', function() { // показываем следующий месяц });

Рассмотрим теперь, какие ошибки можно допустить при реализации переключателей.

Ошибка первая

Пусть некоторый программист реализовал кнопки переключения месяцев:

next.addEventListener('click', function() { elem.textContent = year + ' ' + getMonthName(month + 1); }); prev.addEventListener('click', function() { elem.textContent = year + ' ' + getMonthName(month - 1); });

Этот программист, однако, допустил ошибку, из-за которой месяц переключается только по первому клику, но не по последующим.

Дело в том, что переменная month не изменяется внутри функций - к ее содержимому просто прибавляют единицу и результат отправляют в функцию getMonthName.

Так как наша переменная не изменилась, то при следующем клике в ней по-прежнему будет лежать текущий месяц - и ничего не изменится.

Исправим проблему:

next.addEventListener('click', function() { month = month + 1; elem.textContent = year + ' ' + getMonthName(month); }); prev.addEventListener('click', function() { month = month - 1; elem.textContent = year + ' ' + getMonthName(month); });

Можно упростить:

next.addEventListener('click', function() { elem.textContent = year + ' ' + getMonthName(++month); }); prev.addEventListener('click', function() { elem.textContent = year + ' ' + getMonthName(--month); });

Ошибка вторая

Часто забывают о том, что месяц должен изменяться в определенном диапазоне - от 0 до 11. При достижении границы диапазона мы должны менять год (вперед или назад), а месяц сбрасывать в начальное значение.

Сделаем это:

next.addEventListener('click', function() { if (month === 11) { month = 0; year++; } else { month++; } elem.textContent = year + ' ' + getMonthName(month); }); prev.addEventListener('click', function() { if (month === 0) { month = 11; year--; } else { month--; } elem.textContent = year + ' ' + getMonthName(month); });