Costruire un'applicazione di calendario personalizzata è un ottimo modo per approfondire la comprensione di JavaScript, il modello di oggetto del documento del browser (DOM), e la persistenza dei dati lato client. Levando l'API di archiviazione Web — specificamente Local Storage — è possibile creare un calendario completamente funzionale, organizzato da eventi che funziona interamente nel browser senza bisogno di un server backend o di un database.

Perché costruire un calendario personalizzato?

Le librerie di calendario pre-costruite (come FullCalendar o DayPilot) offrono soluzioni rapide, ma la costruzione di una libreria da zero ti dà il controllo completo dell'interfaccia utente, della gestione dei dati e delle prestazioni. Inoltre, ottieni esperienza pratica con concetti di JavaScript core come l'oggetto , la delegazione degli eventi e l'API ].

Impostazione della struttura HTML

Inizia con uno scheletro HTML pulito. Il calendario ha bisogno di tre componenti principali: una barra di navigazione (per mesi di cambiamento), un contenitore di griglia (per celle di giorno), e un modulo di input dell'evento.

<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>

Per un layout mobile-friendly, si consideri l'utilizzo di una griglia CSS a 7 colonne (una per ogni giorno della settimana).

Styling Calendario con CSS

Pulito, reattivo CSS trasforma l'HTML grezzo in un'interfaccia utilizzabile. Utilizzare una griglia CSS per la griglia del calendario, impostazione [[]. Aggiungi distanziatori per giorni prima del primo del mese. Per accessibilità, garantire un contrasto di colore sufficiente e includere stili su elementi interattivi.

.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;
}

Utilizzare query multimediali per ridurre la dimensione della cella su schermi stretti, e considerare il testo di eventi nascosti e mostrare solo un conteggio.

JavaScript core: Generando il file di calcolo

La funzione centrale, ], calcola il primo giorno del mese e il numero totale di giorni. Usa per ottenere l'indice del giorno della settimana (0 = Domenica). Quindi generare celle in un loop da 1 all'ultimo giorno del mese.

Lavorare con l'oggetto data

L'oggetto è la spina dorsale della logica del calendario. Per ottenere l'ultimo giorno di un mese, utilizzare [[ (il giorno 0 del prossimo mese dà l'ultimo giorno del mese corrente).

Costruire la Griglia

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);
 }
}

Aggiornare il display mese/anno intestazione:

Attaccare gli ascoltatori degli eventi con i pulsanti Precedente e Successivo. Incremento o decremento [, regolare l'anno se necessario (ad esempio, dopo dicembre venire a gennaio del prossimo anno). Dopo l'aggiornamento delle variabili, chiamare di nuovo.

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();
});

Per un'ulteriore usabilità, aggiungere un pulsante Oggi[] che ripristina la vista al mese attuale e mette in evidenza il giorno corrente.

Stoccaggio e recupero eventi con stoccaggio locale

Local Storage[]] fornisce un semplice negozio di valore chiave che sopravvive alle riavviamenti del browser. Utilizzare un modello di chiave coerente, ad esempio , memorizzando JSON array di oggetti di evento. Includere proprietà come , ], , e .

Salvare un nuovo evento

Quando l'utente fa clic sul pulsante "Salva", cattura il valore di ingresso e la data attualmente selezionata. (È possibile aggiungere un raccoglitore di data o rilevare quale cella del giorno è cliccato.) Recuperare eventuali eventi esistenti per quella data da Local Storage, premere il nuovo evento, quindi salvare indietro.

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
}

Caricamento Eventi in celle di giorno

All'interno , per ogni cella giorno non vuota, chiamare una funzione che interroga lo storage locale per quella data chiave. Se gli eventi esistono, passa attraverso di loro e aggiungi elementi alla cella.

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);
 });
}

Cancellare e modificare eventi

Per eliminare, collegare un evento di clic a ogni elemento evento (o utilizzare la delegazione degli eventi). Recuperare l'array per quella data, filtrare l'evento dal suo [, e salvare l'array aggiornato di nuovo a Local Storage.

Caratteristiche avanzate per migliorare la funzionalità

Una volta che il calendario di base sta funzionando, è possibile aggiungere funzionalità che migliorano significativamente l'esperienza dell'utente.

Eventi Color‐Coding per tipo

Permette agli utenti di assegnare categorie (ad esempio, lavoro, personale, salute). Conservare un campo in Local Storage. In CSS, definire classi come , e applicarli dinamicamente.

Rescheduazione Drag-and-Drop

Utilizzare l'API di Trascinamento e Goccia HTML5 per spostare gli eventi tra le celle diurne. Quando un evento viene abbandonato in un giorno diverso, aggiornare la chiave della data in Local Storage: rimuovere l'evento dal suo array di date originale e spingerlo al array della nuova data.

Eventi ricorrenti (Weekly / Mensile)

Nella funzione di carico, calcolare se la data corrente corrisponde alla regola di ricorrenza (ad esempio ogni lunedì) e visualizzare l'evento di conseguenza.

Vista Settimana e Mini Calendario

Una vista della settimana mostra solo i giorni della settimana corrente con più spazio orizzontale. Un piccolo calendario di visualizzazione mese-mese aiuta gli utenti a saltare in qualsiasi data rapidamente.

Rendere il Calendario Responsive e Accessibile

Prova il calendario su varie dimensioni dello schermo. Usa ] query per impilare le celle diurne verticalmente su schermi molto piccoli o per ridurre l'imbottitura. Assicurarsi che tutti gli elementi interattivi siano accessibili alla tastiera: allegare eventi per entrare e fuga. Usa attributi su pulsanti e regioni in tensione per i lettori di schermo per annunciare modifiche del mese e aggiunte evento.

Consigli per la gestione delle prestazioni e dei dati

  • Scrive di memorizzazione batch[]: Invece di leggere/scrivere Local Storage per ogni operazione di evento, memorizzare gli eventi di tutto il mese in un oggetto JavaScript e cambiare periodicamente il colore.
  • Limit Event Size[[]: Tenere gli oggetti degli eventi piccoli. Evitare di memorizzare grandi stringhe o dati binari.
  • Fallback per i limiti di stoccaggio[[]: Lo storage locale è tipicamente bloccato a 5-10 MB.
  • Usa IndexedDB for Large Datasets[]: Se il calendario terrà migliaia di eventi, consideri IndexedDB per migliorare le prestazioni e le capacità di querying.

Conclusioni

Creare un'app di calendario personalizzata con JavaScript e Local Storage è un progetto gratificante che affiora le tue abilità di front-end. Imparerai a manipolare il DOM, a lavorare con le date, gestire lo stato senza un server e gestire le interazioni degli utenti. Il codebase può essere esteso con la sincronizzazione del server, il backup del cloud o l'integrazione con i calendari esterni tramite il ] Google Calendar API[‐FLT:1]].

Per ulteriori informazioni, esplorare la documentazione ]Storage API[ e il [API di drag and Drop[] su MDN.