Błąd przełączania kalendarza w JavaScript
Załóżmy, że chcemy zrobić strzałki do przełączania kalendarza. W takim przypadku można popełnić szereg charakterystycznych błędów. Przyjrzyjmy się im.
Załóżmy, że mamy przyciski przełączania oraz element, do którego dla uproszczenia będziemy wyświetlać nie kalendarz, a po prostu rok i nazwę miesiąca:
<button id="prev">prev</button>
<div id="elem"></div>
<button id="next">next</button>
Pobierzmy referencje do naszych elementów:
let elem = document.querySelector('#elem');
let prev = document.querySelector('#prev');
let next = document.querySelector('#next');
Załóżmy, że mamy również funkcję, która przyjmuje parametrem numer miesiąca i zwraca jego nazwę:
function getMonthName(month) {
let names = [
'sty', 'lut', 'mar', 'kwi', 'maj', 'cze',
'lip', 'sie', 'wrz', 'paź', 'lis', 'gru'
];
return names[month];
}
Po załadowaniu strony pobierzmy bieżący rok i miesiąc:
let date = new Date;
let year = date.getFullYear();
let month = date.getMonth();
Wyświetlmy w naszym elemencie rok i nazwę miesiąca (symulacja kalendarza):
elem.textContent = year + ' ' + getMonthName(month);
Naświetlmy teraz na przełączniki obsługę kliknięć:
prev.addEventListener('click', function() {
// pokazujemy poprzedni miesiąc
});
next.addEventListener('click', function() {
// pokazujemy następny miesiąc
});
Przyjrzyjmy się teraz, jakie błędy można popełnić przy implementacji przełączników.
Błąd pierwszy
Załóżmy, że pewien programista zaimplementował przyciski przełączania miesięcy:
next.addEventListener('click', function() {
elem.textContent = year + ' ' + getMonthName(month + 1);
});
prev.addEventListener('click', function() {
elem.textContent = year + ' ' + getMonthName(month - 1);
});
Ten programista popełnił jednak błąd, przez który miesiąc przełącza się tylko przy pierwszym kliknięciu, ale nie przy kolejnych.
Chodzi o to, że zmienna month nie zmienia się
wewnątrz funkcji - do jej zawartości
po prostu dodaje się jedynkę i wynik
przesyła do funkcji getMonthName.
Ponieważ nasza zmienna się nie zmieniła, to przy następnym kliknięciu będzie w niej nadal bieżący miesiąc - i nic się nie zmieni.
Naprawmy problem:
next.addEventListener('click', function() {
month = month + 1;
elem.textContent = year + ' ' + getMonthName(month);
});
prev.addEventListener('click', function() {
month = month - 1;
elem.textContent = year + ' ' + getMonthName(month);
});
Można uprościć:
next.addEventListener('click', function() {
elem.textContent = year + ' ' + getMonthName(++month);
});
prev.addEventListener('click', function() {
elem.textContent = year + ' ' + getMonthName(--month);
});
Błąd drugi
Często zapomina się o tym, że miesiąc
powinien zmieniać się w określonym
zakresie - od 0 do 11.
Po osiągnięciu granicy zakresu
powinniśmy zmieniać rok (do przodu lub do tyłu),
a miesiąc resetować do początkowej
wartości.
Zróbmy to:
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);
});