← Back to course

Local Storage

Local Storage

Witaj z powrotem.

W poprzedniej lekcji poznałeś formularze i walidację.

Formularze zbierają dane użytkownika.

Walidacja sprawdza, czy te dane mają sens.

Bardzo przydatne.

Bardzo odpowiedzialne.

Bardzo w stylu: “proszę nie wpisywać banana jako email.”

Dzisiaj nauczymy JavaScript czegoś bardzo ciekawego.

Pamięci.

Nie prawdziwej ludzkiej pamięci.

JavaScript nie zapamięta twoich urodzin i nie przyniesie tortu.

Ale może zapamiętać małe kawałki danych w przeglądarce.

To nazywa się local storage.

Local storage pozwala JavaScript zapisywać dane nawet po odświeżeniu strony.

To znaczy, że strona może pamiętać takie rzeczy jak:

Przed local storage JavaScript zapomina wszystko po przeładowaniu strony.

Po local storage JavaScript staje się trochę mniej zapominalski.

Nadal chaotyczny.

Ale robi postępy.

Czego Się Nauczysz

W tej lekcji nauczysz się:

Na końcu tej lekcji twoja strona JavaScript będzie potrafiła pamiętać proste dane.

Nie wszystko.

Nie sekrety.

Nie hasła.

Ale wystarczająco dużo, żeby było użytecznie.

Jak mały notatnik wewnątrz przeglądarki.

Czym Jest Local Storage?

Local storage to funkcja przeglądarki, która pozwala stronom zapisywać małe ilości danych.

Dane zostają w przeglądarce nawet po:

Przykład:

localStorage.setItem("name", "Viktor");

To zapisuje wartość "Viktor" pod kluczem "name".

Potem możemy ją odczytać później:

const name = localStorage.getItem("name");

console.log(name);

Wynik:

Viktor

Przeglądarka zapamiętała wartość.

Bardzo miło.

Bardzo wygodnie.

Lekko magicznie.

Ale to nadal tylko JavaScript.

Ważne Ostrzeżenie

Nie zapisuj w local storage danych wrażliwych.

Nie zapisuj:

Local storage nie jest bezpiecznym magazynem.

Jest użyteczny do prostych danych.

Preferencja motywu?

Dobrze.

Lista zadań?

W porządku.

Hasło?

Nie.

Absolutnie nie.

Bezpieczeństwo to nie dekoracyjna roślinka.

Ma znaczenie.

Utwórz Projekt

Utwórz folder dla tej lekcji:

mkdir javascript-lesson10
cd javascript-lesson10
touch index.html
touch script.js

Twój projekt powinien wyglądać tak:

javascript-lesson10/
  index.html
  script.js

Otwórz folder w edytorze.

Dzisiaj będziemy zapisywać dane w przeglądarce.

Przeglądarka za chwilę stanie się małym notatnikiem.

Oby nie zbyt bałaganiarskim.

Napisz HTML

Otwórz index.html i dodaj:

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Local Storage</title>
</head>
<body>
  <h1>Local Storage</h1>

  <button id="saveButton">Zapisz Imię</button>
  <button id="loadButton">Wczytaj Imię</button>

  <p id="message">Nic jeszcze nie wczytano.</p>

  <script src="script.js"></script>
</body>
</html>

To daje nam:

Prosto.

Małe.

Gotowe, żeby coś zapamiętać.

Co jest więcej, niż mogę powiedzieć o niektórych przeglądarkach po 38 otwartych kartach.

Zapisywanie Danych przez setItem

Otwórz script.js i dodaj:

const saveButton = document.getElementById("saveButton");
const loadButton = document.getElementById("loadButton");
const messageElement = document.getElementById("message");

function saveName() {
  localStorage.setItem("name", "Viktor");
  messageElement.textContent = "Imię zapisane.";
}

saveButton.addEventListener("click", saveName);

Odśwież przeglądarkę.

Kliknij Zapisz Imię.

Komunikat powinien pokazać:

Imię zapisane.

Ta linia jest ważna:

localStorage.setItem("name", "Viktor");

Oznacza:

Zapisz wartość "Viktor" używając klucza "name".

Local storage działa na parach klucz-wartość.

Klucz jest jak etykieta.

Wartość to dane.

Jak etykieta na szufladzie i rzecz w środku szuflady.

Bardzo uporządkowane.

Podejrzanie uporządkowane.

Odczytywanie Danych przez getItem

Teraz dodaj tę funkcję:

function loadName() {
  const savedName = localStorage.getItem("name");
  messageElement.textContent = `Zapisane imię: ${savedName}`;
}

loadButton.addEventListener("click", loadName);

Teraz twój pełny script.js wygląda tak:

const saveButton = document.getElementById("saveButton");
const loadButton = document.getElementById("loadButton");
const messageElement = document.getElementById("message");

function saveName() {
  localStorage.setItem("name", "Viktor");
  messageElement.textContent = "Imię zapisane.";
}

function loadName() {
  const savedName = localStorage.getItem("name");
  messageElement.textContent = `Zapisane imię: ${savedName}`;
}

saveButton.addEventListener("click", saveName);
loadButton.addEventListener("click", loadName);

Kliknij Zapisz Imię.

Odśwież stronę.

Kliknij Wczytaj Imię.

Imię nadal tam jest.

JavaScript je zapamiętał.

Strona została odświeżona.

Dane przetrwały.

Mały cud.

Bez backendu.

Bez bazy danych.

Tylko przeglądarka robi swoje przeglądarkowe rzeczy.

Co Jeśli Dane Nie Istnieją?

Jeśli próbujesz odczytać klucz, który nie istnieje, dostaniesz null.

Przykład:

const savedAge = localStorage.getItem("age");

console.log(savedAge);

Wynik:

null

null oznacza:

Tutaj nic nie ma.

Dlatego dobrze jest sprawdzić dane przed pokazaniem ich użytkownikowi.

Przykład:

function loadName() {
  const savedName = localStorage.getItem("name");

  if (savedName === null) {
    messageElement.textContent = "Nie zapisano jeszcze imienia.";
    return;
  }

  messageElement.textContent = `Zapisane imię: ${savedName}`;
}

Teraz strona zachowuje się lepiej.

Jeśli nie ma zapisanego imienia, mówi o tym.

Bardzo uprzejmie.

Bardzo cywilizowanie.

W przeciwieństwie do losowych błędów JavaScript o północy.

Zapisywanie Inputu Użytkownika

Wpisanie "Viktor" na sztywno jest dobre do nauki.

Ale zwykle chcemy zapisać to, co wpisze użytkownik.

Zaktualizuj index.html:

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Local Storage</title>
</head>
<body>
  <h1>Local Storage</h1>

  <label for="nameInput">Twoje imię:</label>
  <input id="nameInput" type="text" placeholder="Wpisz swoje imię">

  <button id="saveButton">Zapisz Imię</button>
  <button id="loadButton">Wczytaj Imię</button>
  <button id="removeButton">Usuń Imię</button>

  <p id="message">Nic jeszcze nie wczytano.</p>

  <script src="script.js"></script>
</body>
</html>

Teraz zaktualizuj script.js:

const nameInput = document.getElementById("nameInput");
const saveButton = document.getElementById("saveButton");
const loadButton = document.getElementById("loadButton");
const removeButton = document.getElementById("removeButton");
const messageElement = document.getElementById("message");

function saveName() {
  const name = nameInput.value.trim();

  if (name === "") {
    messageElement.textContent = "Najpierw wpisz imię.";
    return;
  }

  localStorage.setItem("name", name);
  messageElement.textContent = "Imię zapisane.";
  nameInput.value = "";
}

function loadName() {
  const savedName = localStorage.getItem("name");

  if (savedName === null) {
    messageElement.textContent = "Nie zapisano jeszcze imienia.";
    return;
  }

  messageElement.textContent = `Zapisane imię: ${savedName}`;
}

function removeName() {
  localStorage.removeItem("name");
  messageElement.textContent = "Imię usunięte.";
}

saveButton.addEventListener("click", saveName);
loadButton.addEventListener("click", loadName);
removeButton.addEventListener("click", removeName);

Teraz użytkownik może wpisać imię.

Zapisać je.

Odświeżyć.

Wczytać ponownie.

Usunąć je.

To jest prawdziwe użycie local storage.

Małe.

Praktyczne.

Użyteczne.

Jak kieszonkowy notatnik, ale z większą liczbą nawiasów klamrowych.

Usuwanie Danych przez removeItem

Ta linia usuwa jeden zapisany element:

localStorage.removeItem("name");

Usuwa wartość zapisaną pod kluczem "name".

Tylko ten element.

Nie wszystko.

To jest przydatne, kiedy użytkownik chce zresetować jedno ustawienie.

Przykład:

localStorage.removeItem("theme");
localStorage.removeItem("username");
localStorage.removeItem("draft");

Konkretnie.

Pod kontrolą.

Bez niepotrzebnego niszczenia.

Bardzo dojrzałe.

Jak na JavaScript.

Czyszczenie Całego Local Storage

Istnieje też:

localStorage.clear();

To usuwa wszystko zapisane w local storage dla tej strony.

Wszystko.

Wszystkie klucze.

Wszystkie wartości.

Znikają.

Używaj ostrożnie.

Przykład:

function clearStorage() {
  localStorage.clear();
}

To przydaje się do przycisków reset.

Ale nie używaj tego losowo.

To cyfrowy odpowiednik sprzątania biurka miotaczem ognia.

Skuteczne.

Ale agresywne.

Local Storage Zapisuje Stringi

Ważny szczegół.

Local storage zapisuje wartości jako stringi.

Przykład:

localStorage.setItem("age", 33);

const age = localStorage.getItem("age");

console.log(age);
console.log(typeof age);

Wynik:

33
string

Nawet jeśli zapisaliśmy liczbę, local storage zwraca string.

To ma znaczenie.

Jeśli potrzebujesz liczby, przekonwertuj ją:

const age = Number(localStorage.getItem("age"));

JavaScript kocha niespodzianki typów.

Miej oczy otwarte.

I może jedną brew uniesioną.

Zapisywanie Obiektów

Local storage nie może bezpośrednio zapisywać obiektów.

To nie działa tak, jak chcesz:

const user = {
  name: "Viktor",
  role: "Student"
};

localStorage.setItem("user", user);

Wynik staje się czymś takim:

[object Object]

Bardzo niepomocne.

Bardzo JavaScript.

Aby zapisać obiekt, zamień go na string przez JSON.stringify.

Przykład:

const user = {
  name: "Viktor",
  role: "Student"
};

localStorage.setItem("user", JSON.stringify(user));

Teraz obiekt jest zapisany jako string JSON.

JSON to tekstowy format danych.

Wygląda podobnie do obiektów JavaScript.

Ale jest tekstem.

Mała różnica.

Duże znaczenie.

Odczytywanie Obiektów

Aby odczytać obiekt z powrotem, użyj JSON.parse.

Przykład:

const savedUser = localStorage.getItem("user");
const user = JSON.parse(savedUser);

console.log(user.name);
console.log(user.role);

Wynik:

Viktor
Student

Pełny przykład:

const user = {
  name: "Viktor",
  role: "Student"
};

localStorage.setItem("user", JSON.stringify(user));

const savedUser = localStorage.getItem("user");
const parsedUser = JSON.parse(savedUser);

console.log(parsedUser);

Schemat jest taki:

JSON.stringify(data)

przy zapisywaniu.

JSON.parse(data)

przy odczytywaniu.

Stringify, żeby zapisać.

Parse, żeby użyć.

Prosto.

Potężnie.

Lekko ceremonialnie.

Zapisywanie Tablic

Tablice też potrzebują JSON.stringify.

Przykład:

const tasks = ["Uczyć się JavaScript", "Ćwiczyć DOM", "Wypić kawę"];

localStorage.setItem("tasks", JSON.stringify(tasks));

Aby je odczytać:

const savedTasks = localStorage.getItem("tasks");
const tasks = JSON.parse(savedTasks);

console.log(tasks);

Wynik:

["Uczyć się JavaScript", "Ćwiczyć DOM", "Wypić kawę"]

To jest bardzo użyteczne.

Bo wiele aplikacji zapisuje listy.

Zadania.

Produkty.

Ulubione.

Ustawienia.

Małe listy rzeczy, na których użytkownikowi zależy.

A czasem listy rzeczy, o których użytkownik i tak zapomni.

Ale przeglądarka pamięta.

Zbuduj Trwałą Listę Zadań

Teraz zbudujemy małą listę zadań, która przetrwa odświeżenie.

Zaktualizuj index.html:

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Local Storage</title>

  <style>
    body {
      font-family: Arial, sans-serif;
      max-width: 700px;
      margin: 60px auto;
      padding: 0 24px;
      background-color: #f3f4f6;
      color: #111827;
    }

    .card {
      background-color: white;
      padding: 24px;
      border: 2px solid #e5e7eb;
      border-radius: 18px;
    }

    h1 {
      font-size: 42px;
    }

    input {
      width: 100%;
      margin-top: 8px;
      padding: 12px;
      border: 2px solid #d1d5db;
      border-radius: 12px;
      font-size: 18px;
      box-sizing: border-box;
    }

    button {
      margin-top: 14px;
      background-color: #2563eb;
      color: white;
      border: none;
      padding: 12px 18px;
      border-radius: 999px;
      font-weight: 700;
      cursor: pointer;
    }

    button:hover {
      background-color: #1d4ed8;
    }

    ul {
      padding-left: 24px;
      margin-top: 20px;
    }

    li {
      font-size: 20px;
      margin-bottom: 10px;
    }

    .message {
      margin-top: 16px;
      font-size: 18px;
      font-weight: 700;
    }
  </style>
</head>
<body>
  <h1>Local Storage</h1>

  <div class="card">
    <label for="taskInput">Nowe zadanie</label>
    <input id="taskInput" type="text" placeholder="Wpisz zadanie">

    <button id="addTaskButton">Dodaj Zadanie</button>
    <button id="clearTasksButton">Wyczyść Zadania</button>

    <p id="message" class="message">Zadania pojawią się poniżej.</p>

    <ul id="taskList"></ul>
  </div>

  <script src="script.js"></script>
</body>
</html>

Teraz zaktualizuj script.js:

const taskInput = document.getElementById("taskInput");
const addTaskButton = document.getElementById("addTaskButton");
const clearTasksButton = document.getElementById("clearTasksButton");
const taskListElement = document.getElementById("taskList");
const messageElement = document.getElementById("message");

let tasks = [];

function saveTasks() {
  localStorage.setItem("tasks", JSON.stringify(tasks));
}

function loadTasks() {
  const savedTasks = localStorage.getItem("tasks");

  if (savedTasks !== null) {
    tasks = JSON.parse(savedTasks);
  }
}

function showTasks() {
  taskListElement.innerHTML = "";

  for (const task of tasks) {
    const listItem = document.createElement("li");
    listItem.textContent = task;
    taskListElement.appendChild(listItem);
  }

  if (tasks.length === 0) {
    messageElement.textContent = "Brak zadań.";
  } else {
    messageElement.textContent = `Masz ${tasks.length} zadanie/zadania.`;
  }
}

function addTask() {
  const task = taskInput.value.trim();

  if (task === "") {
    messageElement.textContent = "Najpierw wpisz zadanie.";
    return;
  }

  tasks.push(task);
  saveTasks();
  showTasks();

  taskInput.value = "";
}

function clearTasks() {
  tasks = [];
  saveTasks();
  showTasks();
}

addTaskButton.addEventListener("click", addTask);
clearTasksButton.addEventListener("click", clearTasks);

loadTasks();
showTasks();

Teraz przetestuj.

Dodaj zadanie.

Odśwież stronę.

Zadanie zostaje.

Dodaj kolejne zadanie.

Odśwież ponownie.

Nadal jest.

Gratulacje.

Zbudowałeś małą trwałą aplikację.

Bez backendu.

Bez bazy danych.

Tylko local storage.

Mała magia frontendu.

Bardzo satysfakcjonujące.

Jak Działa Ten Kod

Ta tablica przechowuje zadania w JavaScript:

let tasks = [];

Ta funkcja zapisuje zadania do local storage:

function saveTasks() {
  localStorage.setItem("tasks", JSON.stringify(tasks));
}

Ta funkcja ładuje zadania z local storage:

function loadTasks() {
  const savedTasks = localStorage.getItem("tasks");

  if (savedTasks !== null) {
    tasks = JSON.parse(savedTasks);
  }
}

Ta funkcja pokazuje zadania na stronie:

function showTasks() {
  taskListElement.innerHTML = "";

  for (const task of tasks) {
    const listItem = document.createElement("li");
    listItem.textContent = task;
    taskListElement.appendChild(listItem);
  }
}

To dodaje zadanie:

tasks.push(task);
saveTasks();
showTasks();

Ważny schemat:

Zaktualizuj dane.

Zapisz dane.

Pokaż dane.

Ten schemat pojawia się wszędzie.

Nawet w większych aplikacjach.

Tylko z większą liczbą plików.

Większą liczbą frameworków.

I większymi obrażeniami emocjonalnymi.

Typowe Błędy

Zapomnienie JSON.stringify

Źle:

localStorage.setItem("tasks", tasks);

Poprawnie:

localStorage.setItem("tasks", JSON.stringify(tasks));

Tablice i obiekty trzeba zamienić na stringi przed zapisaniem.

Inaczej JavaScript robi się dziwny.

Jeszcze dziwniejszy niż zwykle.

Zapomnienie JSON.parse

Źle:

const tasks = localStorage.getItem("tasks");

Poprawnie:

const tasks = JSON.parse(localStorage.getItem("tasks"));

Jeśli zapisałeś JSON, zrób parse przy odczycie.

Stringify przy zapisie.

Parse przy ładowaniu.

Jak pakowanie i rozpakowywanie walizki.

Próba Zapisu Danych Wrażliwych

Zły pomysł:

localStorage.setItem("password", password);

Nie rób tego.

Hasła nie należą do local storage.

Local storage nie jest sejfem.

To bardziej szuflada w twoim pokoju.

Użyteczna.

Ale nie miejsce na sztabki złota.

Zapomnienie Aktualizacji Strony po Zapisie

Jeśli tylko zapiszesz zadanie:

tasks.push(task);
saveTasks();

ale nie wywołasz:

showTasks();

dane są zapisane, ale strona się nie aktualizuje.

Przeglądarka nie czyta w myślach.

Powiedz jej, co ma pokazać.

Praktyka

Stwórz małą stronę, która zapisuje ulubiony kolor.

Strona powinna mieć:

Kiedy użytkownik zapisze kolor, zapisz go w local storage.

Kiedy użytkownik go wczyta, pokaż:

Twój ulubiony kolor to blue.

Bonus:

Zmień tło strony na ten kolor.

Uważaj z kolorami.

Jeśli użytkownik wpisze “pizza”, przeglądarka może nie zrozumieć.

Chociaż duchowo pizza zawsze jest poprawnym wyborem.

Mini Wyzwanie

Stwórz aplikację notatek.

Strona powinna mieć:

Zasady:

To bardzo praktyczne wyzwanie.

Wiele prawdziwych aplikacji zaczyna od tej idei:

Użytkownik coś pisze.

Aplikacja to zapisuje.

Użytkownik wraca później.

Dane nadal tam są.

Prosto.

Użytecznie.

Potężnie.

Podsumowanie

Dzisiaj nauczyłeś się:

To ogromny krok.

Twoje strony mogą teraz pamiętać rzeczy.

Małe rzeczy.

Użyteczne rzeczy.

Rzeczy przeglądarkowe.

JavaScript dostał małą pamięć.

Bardzo użyteczną.

Bardzo niebezpieczną, jeśli użyjesz jej źle.

Jak dać notatnik szopowi.

Następna Lekcja

W następnej lekcji nauczymy się Fetch API.

Fetch pozwala JavaScript pobierać dane z innych miejsc.

API.

Serwerów.

Plików JSON.

Prawdziwych danych ze świata zewnętrznego.

Do tej pory większość danych żyła w naszym kodzie.

Wkrótce JavaScript zacznie rozmawiać z internetem.

Ostrożnie.

Miejmy nadzieję.