Web Storage — přehled možností
Prohlížeč nabízí několik způsobů ukládání dat na straně klienta. Každý má jiný účel, životnost a kapacitu:
| Technologie | Kapacita | Životnost | Dostupnost | Použití |
|---|---|---|---|---|
| localStorage | ~5–10 MB | Trvalá (do smazání) | Jen daný origin | Nastavení, preference, cache |
| sessionStorage | ~5–10 MB | Do zavření záložky | Jen daná záložka | Dočasná data formuláře, wizard |
| Cookies | ~4 KB | Nastavitelná | Server + klient | Autentizace, tracking |
| IndexedDB | Stovky MB | Trvalá | Jen daný origin | Offline app, velká data |
| Cache API | Velká | Trvalá | Service Worker | PWA, offline zdroje |
localStorage API
localStorage ukládá páry klíč–hodnota jako stringy. Pro objekty a pole musíte použít JSON.stringify() a JSON.parse().
// Základní operace
localStorage.setItem('klic', 'hodnota');
localStorage.getItem('klic'); // "hodnota" nebo null
localStorage.removeItem('klic');
localStorage.clear(); // smaže vše!
localStorage.length; // počet položek
localStorage.key(0); // klíč na indexu 0
// Ukládání objektů — MUSÍ přes JSON
const uzivatel = { jmeno: "Jana", vek: 30, tema: "dark" };
localStorage.setItem('uzivatel', JSON.stringify(uzivatel));
// Čtení objektu — MUSÍ přes JSON.parse
const nacteny = JSON.parse(localStorage.getItem('uzivatel'));
// Bezpečné čtení s fallback hodnotou
const tema = JSON.parse(localStorage.getItem('tema')) ?? 'light';
// Utility funkce pro pohodlnější práci
const storage = {
get: (key, fallback = null) => {
try { return JSON.parse(localStorage.getItem(key)) ?? fallback; }
catch { return fallback; }
},
set: (key, value) => localStorage.setItem(key, JSON.stringify(value)),
remove: (key) => localStorage.removeItem(key),
};
// Použití
storage.set('nastaveni', { jazyk: 'cs', notifikace: true });
const nastaveni = storage.get('nastaveni', { jazyk: 'cs' });
🧠 Kvíz: Proč musíme používat JSON.stringify() při ukládání objektu do localStorage?
sessionStorage a cookies
sessionStorage
Stejné API jako localStorage, ale data existují pouze po dobu relace — záložky nebo okna. Zavření záložky = smazání dat. Ideální pro data formulářů (wizard kroky, rozpracovaná data).
// Identické API jako localStorage
sessionStorage.setItem('krok', '2');
sessionStorage.getItem('krok'); // "2"
sessionStorage.removeItem('krok');
// Typické použití — multi-step formulář
function ulozKrok(cislo, data) {
sessionStorage.setItem(`krok_${cislo}`, JSON.stringify(data));
}
function nactiKrok(cislo) {
return JSON.parse(sessionStorage.getItem(`krok_${cislo}`)) ?? {};
}
Cookies z JavaScriptu
// Nastavení cookie
document.cookie = "tema=dark; max-age=2592000; path=/; SameSite=Strict";
// max-age v sekundách (2592000 = 30 dní)
// Čtení cookeis — vždy vrátí celý string!
document.cookie; // "tema=dark; jazyk=cs; ..."
// Utility pro práci s cookies
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
return null;
}
function setCookie(name, value, days = 30) {
const maxAge = days * 24 * 60 * 60;
document.cookie = `${name}=${value}; max-age=${maxAge}; path=/; SameSite=Strict`;
}
function deleteCookie(name) {
document.cookie = `${name}=; max-age=0; path=/`;
}
// POZOR: HttpOnly cookies (autentizace) nelze číst z JS!
// Ty nastavuje server v Set-Cookie hlavičce.
HTML5 formulářové prvky
HTML5 přineslo nové typy inputů, které automaticky zobrazují správnou klávesnici na mobilu, mají nativní validaci a picker UI:
<form action="/submit" method="POST" novalidate>
<!-- Text typy -->
<input type="text" name="jmeno" placeholder="Jan Novák">
<input type="email" name="email" autocomplete="email">
<input type="password" name="heslo" autocomplete="new-password">
<input type="tel" name="telefon" autocomplete="tel">
<input type="url" name="web">
<input type="search" name="q">
<!-- Čísla -->
<input type="number" name="mnozstvi" min="1" max="100" step="1">
<input type="range" name="hlasitost" min="0" max="100" value="50">
<!-- Datum a čas -->
<input type="date" name="datum">
<input type="time" name="cas">
<input type="datetime-local" name="datum_cas">
<input type="month" name="mesic">
<!-- Výběr -->
<input type="color" name="barva" value="#059669">
<input type="file" name="soubor" accept=".pdf,.docx" multiple>
<input type="checkbox" name="souhlas" value="1" required>
<input type="radio" name="pohlavim" value="m">
<!-- Textarea a select -->
<textarea name="zprava" rows="4" maxlength="500"></textarea>
<select name="zeme">
<option value="">Vyberte zemi</option>
<option value="cz" selected>Česká republika</option>
</select>
<!-- Datalist — autocomplete s vlastními možnostmi -->
<input list="ovoce" name="ovoce">
<datalist id="ovoce">
<option value="Jablko">
<option value="Hruška">
</datalist>
</form>
HTML5 nativní validace
Prohlížeče validují formuláře nativně pomocí HTML atributů — bez JavaScriptu. Přidejte novalidate na form pokud chcete vlastní UI, ale stále můžete použít Constraint Validation API.
<!-- Validační atributy -->
<input type="text"
required <!-- povinné pole -->
minlength="3" <!-- minimální počet znaků -->
maxlength="50" <!-- maximální počet znaků -->
pattern="[A-Za-zÀ-ž ]+" <!-- regex vzor -->
>
<input type="number" min="18" max="120">
<input type="email"> <!-- validuje formát email -->
<input type="url"> <!-- validuje formát URL -->
<!-- Vlastní chybová zpráva přes JS -->
input.setCustomValidity("Heslo musí mít alespoň 8 znaků");
input.setCustomValidity(""); // reset — validní
<!-- Constraint Validation API -->
input.validity.valid // boolean
input.validity.valueMissing // required + prázdné
input.validity.typeMismatch // špatný formát (email, url)
input.validity.patternMismatch // nesedí pattern
input.validity.tooShort // kratší než minlength
input.validationMessage // text chyby
input.checkValidity() // boolean, spustí invalid event
form.checkValidity() // zkontroluje celý formulář
🧠 Kvíz: Co způsobí atribut novalidate na elementu <form>?
Vlastní validace v JavaScriptu
Kombinace HTML5 atributů + JS dává plnou kontrolu nad UX validace — vlastní zprávy, živá validace při psaní, vizuální feedback.
🧠 Kvíz: Který event na inputu je vhodný pro živou validaci při psaní?
Praktické cvičení — Nastavení aplikace
Vytvořte stránku "Nastavení profilu" s formulářem (jméno, email, téma light/dark, jazyk). Data ukládejte do localStorage při každé změně a načítejte při startu. Přidejte tlačítko "Obnovit výchozí".
localStorage.getItem() s JSON.parse() při načtení, input event listener pro auto-save, JSON.stringify() při ukládání, vizuální feedback "Uloženo", tlačítko reset s localStorage.removeItem().⚙️ Nastavení profilu
Odznak: Storage & Forms Expert
Zvládáte localStorage, sessionStorage, HTML5 formuláře a validaci.
Taháček — rychlá reference
localStorage
// Uložení (objekty přes JSON!)
localStorage.setItem('klic', JSON.stringify(obj));
// Čtení s fallback
const data = JSON.parse(localStorage.getItem('klic')) ?? vychozi;
// Smazání
localStorage.removeItem('klic');
localStorage.clear(); // vše!
Formulář — submit pattern
form.addEventListener('submit', (e) => {
e.preventDefault(); // zabrání odeslání
const data = Object.fromEntries(new FormData(form));
// { jmeno: "Jana", email: "jana@..." }
// validace + odeslání
});
Validační pattern
function validuj(input, test, zprava) {
const ok = test(input.value);
input.classList.toggle('invalid', !ok);
// zobraz zprávu uživateli
return ok;
}
// Užitečné regex vzory
/^[^\s@]+@[^\s@]+\.[^\s@]+$/ // email
/^(?=.*[A-Z])(?=.*\d).{8,}$/ // heslo (velké + číslo + 8+)
/^\+?[\d\s\-]{9,15}$/ // telefon