Civil & Strukturell teknik
Skapa en anpassad kalenderapp med Javascript och lokal lagring
Table of Contents
Att bygga en anpassad kalenderapplikation är ett utmärkt sätt att fördjupa din förståelse för JavaScript, webbläsaren Dokument Object Model (DOM), och klient-side data persistence. Genom att utnyttja Web Storage API - specifikt Lokal Lagring - kan du skapa en fullt fungerande, händelse-driven kalender som körs helt i webbläsaren utan att behöva en backend server eller databas. Denna handledning går igenom varje steg, från att strukturera HTML till att genomföra avancerade funktioner som drag-and-drop händelsehantering.
Varför bygga en anpassad kalender?
Förbyggda kalenderbibliotek (t.ex. FullCalendar eller DayPilot) erbjuder snabba lösningar, men att bygga en från början ger dig fullständig kontroll över användargränssnittet, datahantering och prestanda. Du får också praktisk erfarenhet med kärn JavaScript-koncept som ]] objekt, händelsedelegation och ] API. Den resulterande appen kan utökas till ett projekthanteringsverktyg, ett bokningssystem eller en personlig tidskrift.
Ställa in HTML-strukturen
Börja med en ren HTML skelett. Kalendern behöver tre huvudkomponenter: en navigeringsfält (för byte av månader), en nätbehållare (för dagceller) och en händelse ingångsform. Använd element med semantiska klassnamn för enkel styling och skript.
<div id="calendar">
<div class="calendar-header">
<button id="prevBtn">←</button>
<h2 id="monthYear"></h2>
<button id="nextBtn">→</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>
kommer att befolkas dynamiskt av JavaScript. För en mobilvänlig layout, överväga att använda ett 7-kolumn CSS-nät (ett för varje dag i veckan). Reservera den första raden för dagsnamn (Sun-Sat).
Styling Kalendern med CSS
Ren, responsiv CSS förvandlar rå HTML till ett användbart gränssnitt. Använd ett CSS-nät för kalendern rutnät, inställning ]. Lägg till rymdskötare i dagar före den första av månaden. För tillgänglighet, se till att tillräcklig färgkontrast och inkludera stilar på interaktiva element. En minimal stilark visas nedan (inline eller länkad).
.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;
}
Använd mediafrågor för att minska cellstorleken på smala skärmar och överväga att dölja händelsetext och visa bara ett räkning.
Kärna JavaScript: Generera Kalendernätet
Alla dynamiska rendering liv i JavaScript. Den centrala funktionen, , beräknar den första dagen i månaden och det totala antalet dagar. Använd ] för att få veckodag index (0 = söndag). generera sedan celler i en slinga från 1 till sista dagen i månaden.
Arbeta med datumobjektet
Objektet är ryggraden i kalenderlogiken. För att få den sista dagen i en månad, använd (dag 0 av nästa månad ger den sista dagen i den aktuella månaden). Förvara den nuvarande månaden och året i globala variabler så navigering kan uppdatera dem.
Bygga släp
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);
}
}
Uppdatera månaden/årsdisplayen i rubriken: ]
Navigation mellan månader
Fästa klickhändelselyssnare på de tidigare och nästa knapparna. Increment eller dekret , justera året om det behövs (t.ex. efter december kommer till januari nästa år). Efter uppdatering av variablerna, ring igen.
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();
});
För extra användbarhet, lägg till en ]] Idag ]] knappen som återställer vyn till den aktuella månaden och belyser dagens dag.
Lagring & Hämta händelser med lokal lagring
]]Local Storage ] ger en enkel nyckelvärde butik som överlever webbläsaren omstarter. Använd ett konsekvent nyckelmönster, t.ex. ], lagra JSON-arrayer av händelseobjekt. Inkludera egenskaper som ]], ], ] och ]].
Spara en ny händelse
När användaren klickar på knappen "Spara" kan du fånga ingångsvärdet och det aktuella datumet. (Du kan lägga till en datumväljare eller upptäcka vilken dagscell som klickas.) Hämta eventuella befintliga händelser för det datumet från lokal lagring, tryck på den nya händelsen och sedan spara tillbaka.
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
}
Laddar händelser i dagceller
Inne ], för varje icke-tomt dag cell, ring en funktion som frågar Lokal Lagring för den datumnyckeln. Om händelser finns, slinga genom dem och lägg till ] element till cellen.
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);
});
}
Ta bort och redigera händelser
För att ta bort, bifoga en klickhändelse till varje händelseelement (eller använd händelsedelegation). Hämta arrayen för det datumet, filtrera bort händelsen genom sin ] och spara den uppdaterade arrayen tillbaka till Lokal lagring. Redigering kan göras genom att dubbelklicka på händelsen, uppmana till ny text och uppdatera array.
Avancerade funktioner för att förbättra funktionaliteten
När den grundläggande kalendern fungerar kan du lägga till funktioner som avsevärt förbättrar användarupplevelsen.
Färg-Coding Events av typ
Tillåt användare att tilldela kategorier (t.ex. arbete, personlig, hälsa) Store en ] fält i lokal lagring. I CSS definierar klasser som ], ] och tillämpa dem dynamiskt.
Drag-and-Drop recheduling
Använd HTML5 Drag och Drop API för att flytta händelser mellan dagceller. När ett evenemang tappas på en annan dag, uppdatera datumnyckeln i Lokal Lagring: ta bort händelsen från dess ursprungliga datum array och trycka den till det nya datumet array.
Återkommande händelser (veckovis / månad)
Lägg till ett "upprepa" alternativ när du sparar ett evenemang. I laddningsfunktionen beräknar du om det aktuella datumet matchar återkommande regeln (t.ex. varje måndag) och visar händelsen därefter. Lagra återfallsregler i en separat Lokal lagringsnyckel för att undvika dubblering.
Week View och Mini Calendar
Växla mellan månad och veckovisning. En veckovisning visar bara den aktuella veckans dagar med mer horisontellt utrymme. En liten mini-kalender för månadsvisa hjälper användarna att hoppa till vilket datum som helst snabbt.
Göra kalendern Responsive och tillgänglig
Testa kalendern på olika skärmstorlekar. Använd ] frågor för att stapla dagceller vertikalt på mycket små skärmar eller för att minska vadslagning. Se till att alla interaktiva element är tangentbordstillgängliga: bifoga händelser för Enter och Escape. Använd attribut på knappar och levande regioner för skärmläsare att meddela månadsändringar och händelsetillägg.
Prestanda och Data Management Tips
- ]Batched Storage Writes: Istället för att läsa/skriva lokal lagring för varje händelseoperation, cache hela månadens händelser i ett JavaScript-objekt och spola förändringar periodiskt.
- ]]Limit Event Size ]: Håll händelseobjekten små. Undvik att lagra stora strängar eller binära data.
- ]Fallback för lagringsgränser: Lokal lagring är vanligtvis begränsad till 5–10 MB varna användare när lagringen är nästan full.
- ] Använd IndexedDB för stora datamängder : Om din kalender kommer att hålla tusentals händelser, överväga ]]IndexedDB ] för bättre prestanda och sökfunktioner.
Slutsats
Skapa en anpassad kalenderapp med JavaScript och Local Storage är ett givande projekt som skärper dina frontend-färdigheter. Du lär dig att manipulera DOM, arbeta med datum, hantera staten utan en server och hantera användarinteraktioner. Kodbasen kan förlängas med serversynkronisering, molnbackup eller integration med externa kalendrar via ] Google Calendar API ]] Börja med grundnätet, lägg till uthållighet och sedan lager på funktioner som drag-och-drop och uppförande.
För vidare läsning, utforska ] Storage API dokumentation ] och ]]]] Drag och Drop API på MDN Happy Coding!