Грешка при пребацивању календара у 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);
});