Construirea unei aplicații calendar personalizate este o modalitate excelentă de a vă aprofunda înțelegerea JavaScript, modelul document de browser (DOM) și persistența datelor client-side. Prin pârghie API Web Storage

De ce să construim un calendar personalizat?

Bibliotecile calendare pre-construite (cum ar fi FullCalendar sau DayPilot) oferă soluții rapide, dar construirea uneia de la zero vă oferă un control complet asupra interfeței de utilizator, a manipulării datelor și a performanței. De asemenea, câștigați experiență hands-on cu concepte JavaScript de bază, cum ar fi obiectul , delegația de evenimente și API . Aplicația rezultată poate fi extinsă într-un instrument de management al proiectelor, un sistem de rezervare sau un jurnal personal.

Configurare structura HTML

Începe cu un schelet HTML curat. Calendarul are nevoie de trei componente principale: o bară de navigare (pentru lunile în schimbare), un container de rețea (pentru celule de zi), și o formă de intrare eveniment. Utilizați elemente cu nume de clasă semantică pentru styling ușor și scripting.

<div id="calendar">
 <div class="calendar-header">
 <button id="prevBtn">&larr;</button>
 <h2 id="monthYear"></h2>
 <button id="nextBtn">&rarr;</button>
 </div>
 <div class="calendar-grid"></div>
 <div class="event-form">
 <input type="text" id="eventInput" placeholder="Add an event..." />
 <button id="saveEvent">Save</button>
 </div>
</div>

va fi populat dinamic de JavaScript. Pentru un layout prietenos mobil, ia în considerare utilizarea unei grile CSS 7-coloană (una pentru fiecare zi a săptămânii). Rezervă primul rând pentru numele de zi (Sun .

Stilarea calendarului cu CSS

CSS-ul curat, receptiv transformă HTML-ul brut într-o interfață utilizabilă. Utilizați o grilă CSS pentru grila de calendar, setarea . Adăugați distanțiatoare pentru zile înainte de prima lună. Pentru accesibilitate, asigurați un contrast de culoare suficient și includeți stiluri pe elemente interactive. O foaie de stil minimă este afișată mai jos (inline sau legate).

.calendar-grid {
 display: grid;
 grid-template-columns: repeat(7, 1fr);
 gap: 2px;
}
.day-cell {
 min-height: 80px;
 border: 1px solid #ccc;
 padding: 4px;
 position: relative;
}
.day-cell.today {
 background-color: #eef;
}
.event {
 font-size: 0.8em;
 background: #4caf50;
 color: #fff;
 padding: 2px 4px;
 margin: 1px 0;
 border-radius: 3px;
 cursor: pointer;
}

Utilizați interogările media pentru a reduce dimensiunea celulei pe ecrane înguste, și să ia în considerare ascunderea textului evenimentului și care arată doar un număr.

Script-ul Java de bază: Generarea grilei calendarului

Toate viata de redare dinamică în JavaScript. Funcția centrală, , calculează prima zi a lunii și numărul total de zile. Utilizați pentru a obține indicele de zi lucrătoare (0 = duminică). Apoi genera celule într-o buclă de la 1 la ultima zi a lunii.

Lucrul cu data obiect

Obiectul este coloana vertebrală a logicii calendarului. Pentru a obține ultima zi a unei luni, utilizați (ziua 0 a lunii următoare oferă ultima zi a lunii curente). Păstrați luna curentă și anul în variabile globale, astfel încât navigarea să le poată actualiza.

Construirea grilei

function renderCalendar() {
 const grid = document.querySelector('.calendar-grid');
 grid.innerHTML = '';

 const firstDay = new Date(currentYear, currentMonth, 1).getDay();
 const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();

 // Add empty cells for days before the 1st
 for (let i = 0; i < firstDay; i++) {
 const empty = document.createElement('div');
 empty.className = 'day-cell empty';
 grid.appendChild(empty);
 }

 // Generate day cells
 for (let day = 1; day <= daysInMonth; day++) {
 const cell = document.createElement('div');
 cell.className = 'day-cell';
 cell.dataset.date = `${currentYear}-${currentMonth + 1}-${day}`;

 const dateSpan = document.createElement('span');
 dateSpan.textContent = day;
 cell.appendChild(dateSpan);

 // Highlight today
 const today = new Date();
 if (currentYear === today.getFullYear() && currentMonth === today.getMonth() && day === today.getDate()) {
 cell.classList.add('today');
 }

 // Load events for this date
 loadEvents(cell);

 grid.appendChild(cell);
 }
}

Actualizează afișarea pe lună/an în antet:

Ataşaţi ascultătorii evenimentului click la butoanele anterioare şi următoare. Increment sau decrement , ajustarea anului, dacă este necesar (de exemplu, după decembrie vin la ianuarie anul viitor). După actualizarea variabilelor, apel din nou.

document.getElementById('prevBtn').addEventListener('click', () => {
 currentMonth--;
 if (currentMonth < 0) {
 currentMonth = 11;
 currentYear--;
 }
 renderCalendar();
});

document.getElementById('nextBtn').addEventListener('click', () => {
 currentMonth++;
 if (currentMonth > 11) {
 currentMonth = 0;
 currentYear++;
 }
 renderCalendar();
});

Pentru o utilizare suplimentară, adăugați un buton Astăzi care resetează vizualizarea către luna curentă și evidențiază ziua curentă.

Stocare & recuperare Evenimente cu stocare locală

Stocarea locală[ oferă un simplu magazin cu valoare-cheie care supraviețuiește reporneşte browser-ul. Utilizați un model de cheie consistent, de exemplu, , stocarea de array-uri JSON de obiecte de eveniment. Include proprietăți precum , , și .

Salvarea unui eveniment nou

Când utilizatorul face clic pe butonul

function saveEvent(dateKey, eventText) {
 const existing = JSON.parse(localStorage.getItem(dateKey)) || [];
 existing.push({ id: Date.now(), text: eventText, time: new Date().toLocaleTimeString() });
 localStorage.setItem(dateKey, JSON.stringify(existing));
 renderCalendar(); // refresh to show new event
}

Încărcare evenimente în celule de zi

În interiorul , pentru fiecare celulă de zi neempulsivă, apelați o funcție care interoghează Storage Local pentru acea cheie de dată. Dacă există evenimente, treceți prin ele și atașați elementele celulei.

function loadEvents(cell) {
 const dateKey = cell.dataset.date;
 const events = JSON.parse(localStorage.getItem(dateKey));
 if (!events) return;

 events.forEach(evt => {
 const eventDiv = document.createElement('div');
 eventDiv.className = 'event';
 eventDiv.textContent = evt.text;
 eventDiv.dataset.id = evt.id;
 // Optional: add a delete button
 cell.appendChild(eventDiv);
 });
}

Ștergerea și editarea evenimentelor

Pentru a șterge, atașați un eveniment click la fiecare element de eveniment (sau folosiți delegația de eveniment). Retrageți array-ul pentru acea dată, filtrați evenimentul prin , și salvați matricea actualizată înapoi la Storage Local. Editarea se poate face prin dublu click pe eveniment, stimulând pentru text nou și actualizarea array-ului.

Caracteristici avansate pentru a spori funcționalitatea

Odată ce calendarul de bază este de lucru, puteți adăuga caracteristici care să îmbunătățească semnificativ experiența utilizatorului.

Color-coding Evenimente după tip

Permite utilizatorilor să atribuie categorii (de exemplu, muncă, personal, sănătate). Păstrați un câmp în Depozitarea locală. În CSS, definiți clase precum , și aplicați-le dinamic.

Reprogramarea tragerii și a dropului

Utilizaţi HTML5 Drag şi Drop API pentru a muta evenimentele între celulele de zi. Când un eveniment este scăzut într-o zi diferită, actualizaţi tasta de dată în Storage Local: eliminaţi evenimentul din matricea sa de date iniţiale şi împingeţi-l la noua data array-uri.

Evenimente recurente (slăbiciune/lunar)

Adăugaţi o opţiune

Vizualizare săptămână și calendar mini

Comută între vedere lună și săptămână. O vedere de săptămână arată doar zilele actuale de săptămână . Un mini calendar lunar mic ajută utilizatorii să sară la orice dată rapid.

Să facem calendarul responsabil şi accesibil

Testați calendarul pe diferite dimensiuni ale ecranului. Utilizați întrebările pentru a stiva celulele de zi vertical pe ecrane foarte mici sau pentru a reduce padding. Asigurați-vă că toate elementele interactive sunt accesibile tastatură: atașați ]] evenimente pentru Enter and Escape. Utilizați atribute pe butoane și regiuni live pentru cititorii de ecran pentru a anunța modificările de lună și completări de evenimente.

Sfaturi de performanță și de gestionare a datelor

  • Scrie în stoc în grup: În loc să citească/scrii Magazinul local pentru fiecare operațiune de eveniment, cache-uri evenimente întreaga lună .
  • [ ]Dimensiune eveniment Limit: Păstrați obiecte eveniment mici. Evitați stocarea siruri mari de caractere sau date binare.
  • Fallback pentru limitele de stocare: Depozitarea locală este de obicei plafonată la 5
  • Utilizați IndexedDB pentru seturi de date mari: Dacă calendarul dumneavoastră va deține mii de evenimente, luați în considerare indexedDB pentru o mai bună performanță și capacități de interogare.

Concluzie

Crearea unei aplicații calendar personalizate cu JavaScript și Storage Local este un proiect recompensator care vă ascute abilitățile de la capatul frontului. Învățați să manipulați DOM, lucrați cu datele, gestionați starea fără server și manevrați interacțiunile cu utilizatorul. Baza de coduri poate fi extinsă cu sincronizarea serverelor, backup-ul cloud sau integrarea cu calendarele externe prin intermediul Google Calendar API. Începeți cu rețeaua de bază, adăugați persistență, și apoi stratați pe caracteristici precum drag-and-drop și evenimente recurente. Rezultatul este un calendar adaptat care se comportă exact cum aveți nevoie de ea.

Pentru lectură ulterioară, explorați documentația API Storage și Drog și drop API pe MDN. Codare fericită!