Ошибка номер раз - html-код вы сгенерировали, но засунуть его пытаетесь куда-то не туда (туда - это view.innerHTML).
Ошибка номер два - обработчик клика после первого переключения месяца отвалится, поскольку элемент, к которому он привязан, будет удалён. Или назначайте обработчик заново при каждом переключении месяца; или делегируйте обработку клика элементу, который не будет перетираться при переключении (view, например); или перепишите построение таблицы так, чтобы кнопки не создавались заново (например, вынесите их и заголовки с днями недели в thead, и перезаписывайте только tbody вместо всей таблицы).
UPD. Ещё ряд косяков поменьше, но упомянуть стоит:
Массивы с днями недели и месяцами не нужны - можно просто
форматировать дату.
Знать количество дней в месяцах тоже не нужно - всегда выводим по шесть недель, начиная с последней недели предыдущего месяца, это минимальное количество полных недель, в которые помещается любой месяц. Почему всегда - чтобы вне зависимости от месяца, размер календаря не изменялся.
Чтобы переключаться месяцами, у объекта даты есть методы -
получили текущий месяц, сделали ему +/- 1,
установили. Заодно и про год думать не надо при переходе от декабря к январю и наоборот - всегда будет правильным.
if (i == day && month == currentMonth) {
calendarView += "<td class='currentday'>" + i + "</td>";
Во-первых, условие кривое - currentMonth это тот месяц, который выводится, а не реально текущий. Т.е., с таким условием currentday у вас в каждом месяце будет, где количество дней больше или равно текущему числу. Во-вторых, условие недостаточно - не учитывается год.
Исправляем, переписываем:
document.body.innerHTML = `
<table class="calendar">
<thead>
<tr>
<th data-step="-1"><</th>
<th class="month" colspan="5"></th>
<th data-step="+1">></th>
</tr>
<tr class="weekdays">${Array.from({ length: 7 }, (_, i) => `
<th>${
new Date(2001, 0, i).toLocaleString('en', { weekday: 'short' })}
</th>`).join('')}
</tr>
</thead>
<tbody></tbody>
</table>
`;
const calendar = document.querySelector('table');
const month = calendar.querySelector('.month');
const tbody = calendar.tBodies[0];
const date = new Date;
calendar.querySelectorAll('[data-step]').forEach(n => {
n.addEventListener('click', showNextMonth);
});
function showNextMonth({ target: { dataset: { step } } }) {
date.setMonth(date.getMonth() + +step);
renderCalendar();
}
function renderCalendar() {
tbody.innerHTML = '';
month.innerText = date.toLocaleString('en', {
year: 'numeric',
month: 'long',
});
const m = date.getMonth();
const d = new Date(date.getFullYear(), m);
const today = new Date().setHours(0, 0, 0, 0);
do {
d.setDate(d.getDate() - 1);
} while (d.getDay() !== 0);
for (let i = 0; i < 6; i++) {
const tr = tbody.insertRow();
for (let j = 0; j < 7; j++, d.setDate(d.getDate() + 1)) {
const td = tr.insertCell();
td.innerHTML = d.getDate();
td.classList.toggle('today', +d === today);
td.classList.toggle('current-month', m === d.getMonth());
}
}
}
renderCalendar();