You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/pl/7-bank-project/1-template-route
localizeflow[bot] f3b5b6aef7
chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes)
7 months ago
..
README.md chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago
assignment.md chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago

README.md

Zbuduj aplikację bankową Część 1: Szablony HTML i trasy w aplikacji internetowej

journey
    title Twoja podróż w tworzeniu aplikacji bankowej
    section Podstawy SPA
      Zrozumienie aplikacji jednostronicowych: 3: Student
      Nauka koncepcji szablonów: 4: Student
      Opanowanie manipulacji DOM: 4: Student
    section Systemy trasowania
      Implementacja trasowania po stronie klienta: 4: Student
      Obsługa historii przeglądarki: 5: Student
      Tworzenie systemów nawigacji: 5: Student
    section Wzorce profesjonalne
      Budowa modularnej architektury: 5: Student
      Stosowanie najlepszych praktyk: 5: Student
      Tworzenie doświadczeń użytkownika: 5: Student

Kiedy komputer pokładowy Apollo 11 nawigował do księżyca w 1969 roku, musiał przełączać się między różnymi programami bez ponownego uruchamiania całego systemu. Nowoczesne aplikacje internetowe działają podobnie zmieniają to, co widzisz, bez przeładowywania wszystkiego od początku. To tworzy płynne, responsywne doświadczenie, którego użytkownicy oczekują dziś.

W przeciwieństwie do tradycyjnych stron internetowych, które przeładowują całe strony przy każdej interakcji, nowoczesne aplikacje webowe aktualizują tylko te części, które wymagają zmiany. Takie podejście, podobnie jak kontrola misji przełączająca się między różnymi wyświetlaczami, przy zachowaniu stałej komunikacji, tworzy to płynne doświadczenie, do którego się przyzwyczailiśmy.

Oto co sprawia, że różnica jest tak dramatyczna:

Tradycyjne aplikacje wielostronicowe Nowoczesne aplikacje jednostronicowe
Nawigacja Pełne przeładowanie strony dla każdego ekranu
Wydajność Wolniejsze ze względu na pełne pobieranie HTML
Doświadczenie użytkownika Drastyczne błyski stron
Udostępnianie danych Trudne między stronami
Tworzenie Wiele plików HTML do utrzymania

Zrozumienie ewolucji:

  • Tradycyjne aplikacje wymagają zapytań serwera przy każdej nawigacji
  • Nowoczesne SPA ładują się raz i dynamicznie aktualizują treść za pomocą JavaScriptu
  • Oczekiwania użytkowników teraz preferują natychmiastowe, bezproblemowe interakcje
  • Korzyści wydajności obejmują zmniejszone zużycie pasma i szybsze odpowiedzi

W tej lekcji zbudujemy aplikację bankową z wieloma ekranami płynnie ze sobą współpracującymi. Tak jak naukowcy używają modułowych instrumentów, które można rekonfigurować do różnych eksperymentów, my użyjemy szablonów HTML jako wielokrotnie wykorzystywanych komponentów, które można wyświetlać według potrzeby.

Będziesz pracować z szablonami HTML (wielokrotnego użytku wzorcami dla różnych ekranów), routingiem w JavaScript (systemem przełączającym się między ekranami) oraz historią przeglądarki API (która sprawia, że działa przycisk wstecz). To te same fundamentalne techniki stosowane w frameworkach takich jak React, Vue oraz Angular.

Pod koniec będziesz mieć działającą aplikację bankową demonstrującą profesjonalne zasady aplikacji jednostronicowej.

mindmap
  root((Single-Page Applications))
    Architecture
      Template System
      Client-side Routing
      State Management
      Event Handling
    Templates
      Reusable Components
      Dynamic Content
      DOM Manipulation
      Content Switching
    Routing
      URL Management
      History API
      Navigation Logic
      Browser Integration
    User Experience
      Szybka Nawigacja
      Płynne Przejścia
      Spójny Stan
      Nowoczesne Interakcje
    Performance
      Zmniejszona Liczba Żądań do Serwera
      Szybsze Przejścia Stron
      Efektywne Wykorzystanie Zasobów
      Lepsza Responsywność

Quiz przed wykładem

Quiz przed wykładem

Czego będziesz potrzebować

Potrzebujemy lokalnego serwera WWW do testowania naszej aplikacji bankowej nie martw się, to łatwiejsze niż brzmi! Jeśli nie masz go jeszcze skonfigurowanego, po prostu zainstaluj Node.js i uruchom npx lite-server z folderu projektu. To polecenie szybko uruchomi lokalny serwer i automatycznie otworzy Twoją aplikację w przeglądarce.

Przygotowanie

Na swoim komputerze utwórz folder o nazwie bank z plikiem index.html w środku. Zaczniemy od tego szablonu HTML boilerplate:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bank App</title>
  </head>
  <body>
    <!-- This is where you'll work -->
  </body>
</html>

Oto co dostarcza ten boilerplate:

  • Ustanawia strukturę dokumentu HTML5 z odpowiednią deklaracją DOCTYPE
  • Konfiguruje kodowanie znaków jako UTF-8 dla wsparcia tekstu międzynarodowego
  • Aktywuje responsywny design za pomocą meta tagu viewport dla kompatybilności mobilnej
  • Ustawia opisowy tytuł pojawiający się na karcie przeglądarki
  • Tworzy czystą sekcję body, gdzie będziemy budować naszą aplikację

📁 Podgląd struktury projektu

Na koniec tej lekcji w Twoim projekcie znajdą się:

bank/
├── index.html      <!-- Main HTML with templates -->
├── app.js          <!-- Routing and navigation logic -->
└── style.css       <!-- (Optional for future lessons) -->

Odpowiedzialność plików:

  • index.html: Zawiera wszystkie szablony i dostarcza strukturę aplikacji
  • app.js: Obsługuje routing, nawigację i zarządzanie szablonami
  • Szablony: Definiują interfejs użytkownika dla logowania, panelu i innych ekranów

Szablony HTML

Szablony rozwiązują podstawowy problem w tworzeniu stron internetowych. Gdy Gutenberg wynalazł ruchomą czcionkę w latach 40. XV wieku, zauważył, że zamiast tworzyć całe strony ręcznie, może tworzyć wielokrotnie używalne bloki liter i układać je według potrzeb. Szablony HTML działają według tej samej zasady zamiast tworzyć oddzielne pliki HTML dla każdego ekranu, definiujesz wielokrotnego użytku struktury, które można wyświetlać w razie potrzeby.

flowchart TD
    A["📋 Definicja szablonu"] --> B["💬 Ukryte w DOM"]
    B --> C["🔍 JavaScript znajduje szablon"]
    C --> D["📋 Klonuj zawartość szablonu"]
    D --> E["🔗 Dołącz do widocznego DOM"]
    E --> F["👁️ Użytkownik widzi zawartość"]
    
    G["Szablon logowania"] --> A
    H["Szablon pulpitu"] --> A
    I["Przyszłe szablony"] --> A
    
    style A fill:#e3f2fd
    style D fill:#e8f5e8
    style F fill:#fff3e0
    style B fill:#f3e5f5

Pomyśl o szablonach jak o planach różnych części Twojej aplikacji. Tak jak architekt tworzy jeden plan i używa go wielokrotnie zamiast rysować identyczne pokoje, my tworzymy szablony raz i wykorzystujemy je według potrzeby. Przeglądarka trzyma te szablony ukryte dopóki JavaScript ich nie aktywuje.

Jeśli chcesz stworzyć wiele ekranów dla strony internetowej, jedną z możliwości byłoby tworzenie po jednym pliku HTML dla każdego ekranu. Jednak takie rozwiązanie ma kilka niedogodności:

  • Musisz przeładowywać cały HTML podczas przełączania ekranu, co może być wolne.
  • Trudno jest współdzielić dane między różnymi ekranami.

Innym podejściem jest posiadanie tylko jednego pliku HTML i zdefiniowanie wielu szablonów HTML za pomocą elementu <template>. Szablon to wielokrotnego użytku blok HTML, który nie jest wyświetlany przez przeglądarkę i musi zostać zainstancjonowany w czasie wykonywania za pomocą JavaScript.

Zbudujmy to

Stworzymy aplikację bankową z dwoma głównymi ekranami: stroną logowania i panelem głównym. Najpierw dodajmy element zastępczy do naszego body HTML to tutaj będą się wyświetlać wszystkie nasze różne ekrany:

<div id="app">Loading...</div>

Zrozumienie tego elementu zastępczego:

  • Tworzy kontener o identyfikatorze „app”, gdzie będą wyświetlane wszystkie ekrany
  • Pokazuje komunikat „Loading...” do momentu, aż JavaScript zainicjalizuje pierwszy ekran
  • Zapewnia jedno miejsce do umocowania naszej dynamicznej zawartości
  • Umożliwia łatwe odwoływanie się z JavaScript za pomocą document.getElementById()

💡 Wskazówka eksperta: Ponieważ zawartość tego elementu będzie zastępowana, możesz wstawić tam komunikat ładowania lub wskaźnik, który będzie widoczny podczas ładowania aplikacji.

Następnie dodajmy poniżej szablon HTML dla strony logowania. Na razie umieścimy tam tylko tytuł i sekcję zawierającą link, który posłuży nam do nawigacji.

<template id="login">
  <h1>Bank App</h1>
  <section>
    <a href="/dashboard">Login</a>
  </section>
</template>

Analiza szablonu logowania:

  • Definiuje szablon o unikalnym identyfikatorze „login” do celów JavaScript
  • Zawiera główne nagłówki określające markę aplikacji
  • Posiada semantyczny element <section>, aby grupować powiązane treści
  • Dostarcza link nawigacyjny, który przeprowadzi użytkownika do panelu głównego

Następnie dodamy kolejny szablon HTML dla strony panelu głównego. Ta strona będzie zawierać różne sekcje:

  • Nagłówek z tytułem i linkiem do wylogowania
  • Aktualne saldo konta bankowego
  • Listę transakcji wyświetlaną w tabeli
<template id="dashboard">
  <header>
    <h1>Bank App</h1>
    <a href="/login">Logout</a>
  </header>
  <section>
    Balance: 100$
  </section>
  <section>
    <h2>Transactions</h2>
    <table>
      <thead>
        <tr>
          <th>Date</th>
          <th>Object</th>
          <th>Amount</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </section>
</template>

Poznajmy każdą część tego panelu:

  • Buduje stronę za pomocą semantycznego elementu <header> zawierającego nawigację
  • Wyświetla tytuł aplikacji spójnie na wszystkich ekranach dla identyfikacji marki
  • Zapewnia link wylogowania przekierowujący z powrotem do ekranu logowania
  • Pokazuje aktualne saldo konta w dedykowanej sekcji
  • Organizuje dane transakcji za pomocą prawidłowo zbudowanej tabeli HTML
  • Definiuje nagłówki tabeli dla kolumn Data, Obiekt i Kwota
  • Pozostawia ciało tabeli puste do dynamicznego wstawiania zawartości później

💡 Wskazówka eksperta: Podczas tworzenia szablonów HTML, jeśli chcesz zobaczyć ich wygląd, możesz skomentować linie <template> oraz </template> otaczając je <!-- -->.

🔄 Sprawdzenie pedagogiczne

Zrozumienie systemu szablonów: Przed wdrożeniem JavaScript upewnij się, że rozumiesz:

  • Jak szablony różnią się od zwykłych elementów HTML
  • Dlaczego szablony są niewidoczne, dopóki nie są aktywowane przez JavaScript
  • Znaczenie semantycznej struktury HTML w szablonach
  • Jak szablony umożliwiają tworzenie wielokrotnie używalnych komponentów UI

Szybki autotest: Co się stanie, jeśli usuniesz tagi <template> wokół swojego HTML? Odpowiedź: Zawartość stanie się od razu widoczna i traci funkcjonalność szablonu

Zalety architektury: Szablony oferują:

  • Wielokrotne użycie: Jedna definicja, wiele instancji
  • Wydajność: Brak zbędnego parsowania HTML
  • Łatwość utrzymania: Centralna struktura UI
  • Elastyczność: Dynamiczna zmiana zawartości

Dlaczego Twoim zdaniem używamy atrybutów id na szablonach? Czy moglibyśmy użyć czegoś innego, np. klas?

Ożywianie szablonów za pomocą JavaScriptu

Teraz musimy sprawić, żeby nasze szablony działały. Tak jak drukarka 3D bierze cyfrowy szkic i tworzy fizyczny obiekt, tak JavaScript bierze nasze ukryte szablony i tworzy widoczne, interaktywne elementy, które użytkownicy mogą zobaczyć i używać.

Proces ten przebiega w trzech konsekwentnych krokach, które tworzą podstawę nowoczesnego tworzenia stron. Gdy zrozumiesz ten wzorzec, zobaczysz go w wielu frameworkach i bibliotekach.

Jeśli w tej chwili otworzysz swój plik HTML w przeglądarce, zobaczysz, że przestaje pokazywać tylko „Loading...”. Dzieje się tak dlatego, że musimy dodać trochę kodu JavaScript, który zainstancjonuje i wyświetli szablony HTML.

Instancjonowanie szablonu zwykle odbywa się w 3 krokach:

  1. Pobranie elementu szablonu w DOM, na przykład za pomocą document.getElementById.
  2. Sklonowanie elementu szablonu za pomocą cloneNode.
  3. Dołączenie go do DOM pod elementem widocznym, np. przy użyciu appendChild.
flowchart TD
    A[🔍 Krok 1: Znajdź Szablon] --> B[📋 Krok 2: Sklonuj Szablon]
    B --> C[🔗 Krok 3: Dołącz do DOM]
    
    A1["document.getElementById('login')"] --> A
    B1["template.content.cloneNode(true)"] --> B  
    C1["app.appendChild(view)"] --> C
    
    C --> D[👁️ Szablon Widoczny dla Użytkownika]
    
    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style C fill:#e8f5e8
    style D fill:#fff3e0

Graficzne omówienie procesu:

  • Krok 1 lokalizuje ukryty szablon w strukturze DOM
  • Krok 2 tworzy działającą kopię, którą można bezpiecznie modyfikować
  • Krok 3 wstawia kopię do widocznego obszaru strony
  • Efekt to funkcjonalny ekran, z którym użytkownik może interagować

Dlaczego musimy sklonować szablon zanim go dodamy do DOM? Co by się stało, gdybyśmy pominęli ten krok?

Zadanie

Utwórz nowy plik o nazwie app.js w folderze projektu i zaimportuj go w sekcji <head> Twojego HTML:

<script src="app.js" defer></script>

Zrozumienie importu skryptu:

  • Łączy plik JavaScript z naszym dokumentem HTML
  • Używa atrybutu defer, aby skrypt uruchomił się po zakończeniu parsowania HTML
  • Zapewnia dostęp do wszystkich elementów DOM, ponieważ są już w pełni załadowane przed wykonaniem skryptu
  • Podąża za nowoczesnymi najlepszymi praktykami ładowania skryptów i wydajności

Teraz w app.js utworzymy nową funkcję updateRoute:

function updateRoute(templateId) {
  const template = document.getElementById(templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Krok po kroku, co tu się dzieje:

  • Lokalizuje element szablonu po jego unikalnym ID
  • Tworzy głęboką kopię zawartości szablonu za pomocą cloneNode(true)
  • Znajduje kontener aplikacji, gdzie ta zawartość będzie wyświetlana
  • Czyści całą istniejącą zawartość kontenera aplikacji
  • Wstawia sklonowaną zawartość szablonu do widocznego DOM

Teraz wywołaj tę funkcję z jednym ze szablonów i zobacz efekt.

updateRoute('login');

Co osiąga to wywołanie funkcji:

  • Aktywuje szablon logowania, przekazując jego ID jako parametr
  • Pokazuje jak programowo przełączać się między różnymi ekranami aplikacji
  • Wyświetla ekran logowania zamiast komunikatu „Loading...”

Jaki jest cel tego kodu app.innerHTML = '';? Co się stanie bez niego?

Tworzenie tras

Routing to w zasadzie łączenie URL-i z odpowiednią treścią. Wyobraź sobie, jak dawni operatorzy telefoniczni używali centrali do łączenia rozmów przyjmowali połączenie przychodzące i kierowali je do właściwego celu. Routing sieciowy działa podobnie, przyjmując żądanie URL i decydując, którą treść wyświetlić.

flowchart LR
    A["🌐 Ścieżka URL<br/>/dashboard"] --> B["🗺️ Obiekt tras<br/>Wyszukiwanie"]
    B --> C["🎯 ID szablonu<br/>'dashboard'"]
    C --> D["📌 Znajdź szablon<br/>getElementById"]
    D --> E["👁️ Wyświetl ekran<br/>Klonuj i dołącz"]
    
    F["📍 /login"] --> G["🎯 'login'"]
    H["📍 /unknown"] --> I["❌ Nie znaleziono"]
    I --> J["🔄 Przekieruj do /login"]
    
    style B fill:#e3f2fd
    style E fill:#e8f5e8
    style I fill:#ffebee
    style J fill:#fff3e0

Tradycyjnie serwery internetowe obsługiwały to przez serwowanie różnych plików HTML dla różnych adresów URL. Ponieważ budujemy aplikację jednostronicową, musimy obsłużyć routing samodzielnie za pomocą JavaScriptu. To podejście daje nam większą kontrolę nad doświadczeniem użytkownika i wydajnością.

flowchart LR
    A["🌐 Ścieżka URL<br/>/dashboard"] --> B["🗺️ Obiekt tras<br/>Wyszukiwanie"]
    B --> C["🎯 ID szablonu<br/>'dashboard'"]
    C --> D["📄 Znajdź szablon<br/>getElementById"]
    D --> E["👁️ Wyświetl ekran<br/>Klonuj i dołącz"]
    
    F["📍 /login"] --> G["🎯 'login'"]
    H["📍 /unknown"] --> I["❌ Nie znaleziono"]
    I --> J["🔄 Przekieruj do /login"]
    
    style B fill:#e3f2fd
    style E fill:#e8f5e8
    style I fill:#ffebee
    style J fill:#fff3e0

Zrozumienie przepływu routingu:

  • Zmiany URL wywołują sprawdzenie w naszej konfiguracji tras
  • Prawidłowe trasy są mapowane na konkretne ID szablonów do renderowania
  • Nieprawidłowe trasy wywołują zachowanie zapasowe, aby uniknąć błędnych stanów
  • Renderowanie szablonu przebiega zgodnie z poznanym wcześniej trzyetapowym procesem

Mówiąc o aplikacji webowej, Routing to intencja mapowania URL na konkretne ekrany, które powinny się wyświetlać. W serwisie z wieloma plikami HTML odbywa się to automatycznie, ponieważ ścieżki plików odzwierciedlają się w URL. Na przykład, mając w folderze projektu takie pliki:

mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html

Jeśli utworzysz serwer webowy z mywebsite jako rootem, mapowanie URL będzie wyglądać:

https://site.com            --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/     --> mywebsite/admin/index.html

Jednak w naszej aplikacji internetowej mamy jeden plik HTML zawierający wszystkie ekrany, więc to domyślne zachowanie nam nie pomoże. Musimy stworzyć tę mapę ręcznie i zaktualizować wyświetlany szablon za pomocą JavaScriptu.

Zadanie

Użyjemy prostego obiektu, aby zaimplementować mapę między ścieżkami URL a naszymi szablonami. Dodaj ten obiekt na górze pliku app.js.

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard' },
};

Zrozumienie tej konfiguracji tras:

  • Definiuje mapowanie między ścieżkami URL i identyfikatorami szablonów
  • Używa składni obiektu, gdzie klucze to ścieżki URL, a wartości zawierają informacje o szablonach
  • Umożliwia łatwe wyszukanie, który szablon wyświetlić dla danego URL
  • Zapewnia skalowalną strukturę do dodawania nowych tras w przyszłości Teraz zmodyfikujmy trochę funkcję updateRoute. Zamiast przekazywać bezpośrednio templateId jako argument, chcemy go pobrać, najpierw patrząc na aktualny URL, a następnie użyć naszej mapy, by uzyskać odpowiadającą wartość ID szablonu. Możemy użyć window.location.pathname, aby pobrać tylko część ścieżki z URL.
function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Analiza tego, co się tutaj dzieje:

  • Wyciąga aktualną ścieżkę z adresu URL przeglądarki za pomocą window.location.pathname
  • Wyszukuje odpowiadającą konfigurację trasy w obiekcie routes
  • Pobiera ID szablonu z konfiguracji trasy
  • Realizuje ten sam proces renderowania szablonu co wcześniej
  • Tworzy dynamiczny system reagujący na zmiany URL

Tutaj odwzorowaliśmy trasy, które zadeklarowaliśmy, na odpowiadające im szablony. Możesz sprawdzić, że działa to poprawnie, zmieniając adres URL ręcznie w przeglądarce.

Co się stanie, jeśli wpiszesz nieznaną ścieżkę w URL? Jak moglibyśmy to rozwiązać?

Dodawanie Nawigacji

Po ustaleniu routingu użytkownicy potrzebują sposobu na poruszanie się po aplikacji. Tradycyjne strony internetowe przeładowują całe strony po kliknięciu w linki, ale my chcemy aktualizować zarówno URL, jak i treść bez odświeżania strony. Tworzy to płynniejsze doświadczenie podobne do tego, jak aplikacje desktopowe przełączają się między różnymi widokami.

Musimy skoordynować dwie rzeczy: aktualizację adresu URL w przeglądarce, aby użytkownicy mogli dodawać strony do zakładek i udostępniać linki, oraz wyświetlanie odpowiedniej zawartości. Jeśli zostanie to poprawnie zaimplementowane, tworzy to płynną nawigację, jakiej użytkownicy oczekują w nowoczesnych aplikacjach.

sequenceDiagram
    participant User
    participant Browser
    participant App
    participant Template
    
    User->>Browser: Kliknięcie linku "Zaloguj się"
    Browser->>App: wywołanie zdarzenia onclick
    App->>App: preventDefault() i nawigacja('/dashboard')
    App->>Browser: history.pushState('/dashboard')
    Browser->>Browser: URL aktualizowany na /dashboard
    App->>App: wywołanie updateRoute()
    App->>Template: Znajdź i sklonuj szablon pulpitu
    Template->>App: Zwróć sklonowaną zawartość
    App->>Browser: Zamień zawartość aplikacji na szablon
    Browser->>User: Wyświetl ekran pulpitu
    
    Note over User,Template: Użytkownik kliknął przycisk wstecz przeglądarki
    
    User->>Browser: Kliknięcie przycisku wstecz
    Browser->>Browser: Historia cofa się do /login
    Browser->>App: wywołanie zdarzenia popstate
    App->>App: automatyczne wywołanie updateRoute()
    App->>Template: Znajdź i sklonuj szablon logowania
    Template->>App: Zwróć sklonowaną zawartość
    App->>Browser: Zamień zawartość aplikacji na szablon
    Browser->>User: Wyświetl ekran logowania

🔄 Pedagogiczne podsumowanie

Architektura Single-Page Application: Zweryfikuj swoją wiedzę na temat całego systemu:

  • Czym różni się routing po stronie klienta od tradycyjnego routingu po stronie serwera?
  • Dlaczego API History jest niezbędne do prawidłowej nawigacji SPA?
  • Jak szablony umożliwiają dynamiczną zawartość bez przeładowania strony?
  • Jaką rolę odgrywa obsługa zdarzeń w przechwytywaniu nawigacji?

Integracja systemu: Twoja SPA pokazuje:

  • Zarządzanie szablonami: wielokrotnego użytku komponenty UI z dynamiczną treścią
  • Routing po stronie klienta: zarządzanie URL bez zapytań do serwera
  • Architektura zdarzeniowa: responsywna nawigacja i interakcje użytkownika
  • Integracja z przeglądarką: obsługa historii i przycisków wstecz/dalej
  • Optymalizacja wydajności: szybkie przejścia i zmniejszenie obciążenia serwera

Wzorce profesjonalne: Zaimplementowałeś:

  • Oddzielenie modelu od widoku: szablony oddzielone od logiki aplikacji
  • Zarządzanie stanem: synchronizacja stanu URL z wyświetlaną zawartością
  • Progresywne ulepszanie: JavaScript usprawnia podstawową funkcjonalność HTML
  • Doświadczenie użytkownika: płynna nawigacja jak w aplikacjach bez przeładowań

<EFBFBD> Wgląd w architekturę: Komponenty systemu nawigacji

Co budujesz:

  • 🔄 Zarządzanie URL: Aktualizacja paska adresu przeglądarki bez przeładowania strony
  • 📋 System szablonów: Dynamiczna zmiana treści w zależności od bieżącej trasy
  • 📚 Integracja historii: Utrzymanie działania przycisków wstecz/dalej
  • 🛡️ Obsługa błędów: Eleganckie rozwiązania dla niepoprawnych lub brakujących tras

Jak współdziałają komponenty:

  • Nasłuchują zdarzeń nawigacji (kliknięcia, zmiany historii)
  • Aktualizują URL za pomocą API History
  • Renderują odpowiedni szablon dla nowej trasy
  • Utrzymują płynne doświadczenie użytkownika

Następnym krokiem naszej aplikacji jest dodanie możliwości nawigowania między stronami bez konieczności ręcznego zmieniania URL. Obejmuje to dwie rzeczy:

  1. Aktualizację bieżącego URL
  2. Aktualizację wyświetlanego szablonu na podstawie nowego URL

Drugą częścią zajęliśmy się już za pomocą funkcji updateRoute, teraz musimy wymyślić, jak zaktualizować bieżący URL.

Będziemy musieli użyć JavaScript, a konkretnie history.pushState, która pozwala zaktualizować URL i utworzyć nowy wpis w historii przeglądania, bez przeładowania HTML.

⚠️ Ważna uwaga: Chociaż element HTML anchor <a href> może być użyty samodzielnie do tworzenia odnośników do różnych URL, domyślnie spowoduje przeładowanie strony. Należy zapobiec temu zachowaniu podczas obsługi routingu za pomocą własnego JavaScript, stosując funkcję preventDefault() na zdarzeniu kliknięcia.

Zadanie

Stwórzmy nową funkcję, której będziemy mogli użyć do nawigacji w naszej aplikacji:

function navigate(path) {
  window.history.pushState({}, path, path);
  updateRoute();
}

Zrozumienie tej funkcji nawigacyjnej:

  • Aktualizuje URL przeglądarki na nową ścieżkę za pomocą history.pushState
  • Dodaje nowy wpis do stosu historii przeglądania w celu prawidłowego działania przycisków wstecz/dalej
  • Wywołuje funkcję updateRoute(), aby wyświetlić odpowiedni szablon
  • Utrzymuje doświadczenie SPA bez przeładowań strony

Ta metoda najpierw aktualizuje bieżący URL na podstawie podanej ścieżki, następnie aktualizuje szablon. Właściwość window.location.origin zwraca korzeń adresu URL, pozwalając zrekonstruować pełny adres z podanej ścieżki.

Mając tę funkcję, możemy zająć się problemem, który mamy, jeśli ścieżka nie pasuje do żadnej zdefiniowanej trasy. Zmienimy funkcję updateRoute, dodając zapasową trasę, jeśli nie znajdziemy dopasowania.

function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  if (!route) {
    return navigate('/login');
  }

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Kluczowe punkty do zapamiętania:

  • Sprawdza, czy istnieje trasa dla bieżącej ścieżki
  • Przekierowuje na stronę logowania, gdy dostęp do niepoprawnej trasy zostanie podjęty
  • Zapewnia mechanizm zapasowy zapobiegający przerwanym nawigacjom
  • Gwarantuje, że użytkownicy zawsze zobaczą poprawny ekran, nawet przy błędnych URL

Jeśli nie znajdziemy trasy, teraz przekierujemy na stronę login.

Stwórzmy teraz funkcję, która pobierze adres URL podczas kliknięcia linku oraz zapobiegnie domyślnemu zachowaniu przeglądarki:

function onLinkClick(event) {
  event.preventDefault();
  navigate(event.target.href);
}

Analiza tego obsługiwacza kliknięć:

  • Zapobiega domyślnemu zachowaniu linku w przeglądarce za pomocą preventDefault()
  • Wyciąga docelowy adres URL z klikniętego elementu linku
  • Wywołuje naszą własną funkcję nawigacyjną zamiast przeładowywania strony
  • Utrzymuje płynne doświadczenie aplikacji jednostronicowej
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>

Co osiąga powiązanie onclick:

  • Łączy każdy link z naszym niestandardowym systemem nawigacji
  • Przekazuje zdarzenie kliknięcia do naszej funkcji onLinkClick do obsługi
  • Umożliwia płynną nawigację bez przeładowań strony
  • Utrzymuje poprawną strukturę URL, którą użytkownicy mogą zakładać w zakładkach lub udostępniać

Atrybut onclick łączy zdarzenie click z kodem JavaScript, tutaj wywołaniem funkcji navigate().

Spróbuj kliknąć w te linki — teraz powinieneś móc nawigować między różnymi ekranami swojej aplikacji.

Metoda history.pushState jest częścią standardu HTML5 i została zaimplementowana w wszystkich nowoczesnych przeglądarkach. Jeśli tworzysz aplikację webową dla starszych przeglądarek, istnieje sposób, by zastąpić to API: używając hasza (#) przed ścieżką, możesz zaimplementować routing działający z tradycyjnym nawigowaniem linków i bez przeładowania strony, ponieważ jego celem było tworzenie linków wewnętrznych w obrębie jednej strony.

Umożliwienie działania przycisków Wstecz i Dalej

Przyciski wstecz i dalej są fundamentem przeglądania stron internetowych, podobnie jak kontrolerzy misji NASA mogą przeglądać poprzednie stany systemów podczas misji kosmicznych. Użytkownicy oczekują, że te przyciski będą działać, a gdy tak nie jest, psuje to oczekiwane doświadczenie przeglądania.

Nasza aplikacja jednostronicowa wymaga dodatkowej konfiguracji, by to wspierać. Przeglądarka utrzymuje stos historii (który dodajemy za pomocą history.pushState), ale gdy użytkownicy poruszają się po historii, nasza aplikacja musi na to zareagować, aktualizując wyświetlaną zawartość.

sequenceDiagram
    participant User
    participant Browser
    participant App
    participant Template
    
    User->>Browser: Kliknięcie linku "Zaloguj się"
    Browser->>App: wywołanie zdarzenia onclick
    App->>App: preventDefault() & przejdź do('/dashboard')
    App->>Browser: history.pushState('/dashboard')
    Browser->>Browser: URL aktualizuje się na /dashboard
    App->>App: wywołanie updateRoute()
    App->>Template: Znajdź i sklonuj szablon dashboardu
    Template->>App: Zwróć sklonowaną zawartość
    App->>Browser: Zastąp zawartość aplikacji szablonem
    Browser->>User: Wyświetl ekran dashboardu
    
    Note over User,Template: Użytkownik klika przycisk wstecz w przeglądarce
    
    User->>Browser: Kliknięcie przycisku wstecz
    Browser->>Browser: Historia cofa się do /login
    Browser->>App: wywołanie zdarzenia popstate
    App->>App: automatyczne wywołanie updateRoute()
    App->>Template: Znajdź i sklonuj szablon logowania
    Template->>App: Zwróć sklonowaną zawartość
    App->>Browser: Zastąp zawartość aplikacji szablonem
    Browser->>User: Wyświetl ekran logowania

Kluczowe punkty interakcji:

  • Działania użytkownika wywołują nawigację przez kliknięcia lub przyciski przeglądarki
  • Aplikacja przechwytuje kliknięcia linków zapobiegając przeładowaniu strony
  • API History zarządza zmianami URL i stosem historii przeglądarki
  • Szablony dostarczają strukturę zawartości dla każdego ekranu
  • Nasłuchiwacze zdarzeń zapewniają reakcję aplikacji na wszystkie typy nawigacji

Użycie history.pushState tworzy nowe wpisy w historii nawigacji przeglądarki. Możesz to sprawdzić, przytrzymując przycisk wstecz w przeglądarce — powinno się pokazać coś takiego:

Screenshot of navigation history

Jeśli spróbujesz kilka razy kliknąć przycisk wstecz, zauważysz, że aktualny URL się zmienia, a historia jest aktualizowana, ale nadal wyświetlany jest ten sam szablon.

Dzieje się tak, ponieważ aplikacja nie wie, że musi wywołać updateRoute() przy każdej zmianie historii. Jeśli spojrzysz na dokumentację history.pushState, zobaczysz, że jeśli stan się zmienia — czyli przechodzimy do innego URL — wywoływane jest zdarzenie popstate. Wykorzystamy to, by naprawić ten problem.

Zadanie

Aby mieć pewność, że wyświetlany szablon jest aktualizowany podczas zmiany historii przeglądarki, podłączymy nową funkcję wywołującą updateRoute(). Zrobimy to na dole naszego pliku app.js:

window.onpopstate = () => updateRoute();
updateRoute();

Co się dzieje podczas integracji historii:

  • Nasłuchuje zdarzeń popstate, które występują gdy użytkownicy nawigują za pomocą przycisków przeglądarki
  • Używa funkcji strzałkowej dla zwięzłej składni obsługi zdarzeń
  • Automatycznie wywołuje updateRoute() za każdym razem, gdy zmienia się stan historii
  • Inicjalizuje aplikację wywołując updateRoute() podczas pierwszego załadowania strony
  • Zapewnia poprawne wyświetlanie szablonu niezależnie od metody nawigacji użytkownika

💡 Profesjonalna wskazówka: Użyliśmy tutaj funkcji strzałkowej do zadeklarowania obsługi zdarzenia popstate ze względu na jej zwięzłość, ale zwykła funkcja działałaby tak samo.

Przypomnij sobie wideo o funkcjach strzałkowych:

Arrow Functions

🎥 Kliknij powyższy obraz, by obejrzeć wideo o funkcjach strzałkowych.

Spróbuj teraz korzystać z przycisków wstecz i dalej swojej przeglądarki i sprawdź, czy wyświetlana trasa jest tym razem poprawnie aktualizowana.

Co możesz zrobić w następnych 5 minutach

  • Przetestuj nawigację swojej aplikacji bankowej za pomocą przycisków wstecz/dalej w przeglądarce
  • Spróbuj wpisać ręcznie różne URL w pasku adresu, by przetestować routing
  • Otwórz DevTools przeglądarki i sprawdź, jak szablony są klonowane do DOM
  • Eksperymentuj z dodawaniem poleceń console.log, aby śledzić przebieg routingu

🎯 Co możesz osiągnąć w ciągu godziny

  • Wykonaj quiz po lekcji i zrozum koncepcje architektury SPA
  • Dodaj stylizację CSS, aby Twoje szablony aplikacji bankowej wyglądały profesjonalnie
  • Zaimplementuj stronę błędu 404 z odpowiednią obsługą błędów
  • Stwórz stronę z podziękowaniami z dodatkowymi funkcjami routingu
  • Dodaj stany ładowania i przejścia między szablonami

📅 Twój tygodniowy plan rozwoju SPA

  • Ukończ pełną aplikację bankową z formularzami, zarządzaniem danymi i trwałością
  • Dodaj zaawansowane funkcje routingu, takie jak parametry tras i zagnieżdżone trasy
  • Zaimplementuj strażników nawigacji i routing oparty na uwierzytelnianiu
  • Stwórz wielokrotnego użytku komponenty szablonów i bibliotekę komponentów
  • Dodaj animacje i przejścia w celu płynniejszego doświadczenia użytkownika
  • Wdróż swoją SPA na platformę hostingową i poprawnie skonfiguruj routing

🌟 Twój miesięczny kurs mistrzowski architektury frontendu

  • Buduj kompleksowe SPA używając nowoczesnych frameworków jak React, Vue czy Angular
  • Naucz się zaawansowanych wzorców zarządzania stanem i bibliotek
  • Opanuj narzędzia budowania i workflowy deweloperskie dla tworzenia SPA
  • Zaimplementuj funkcje Progressive Web App i pracę offline
  • Studiuj techniki optymalizacji wydajności dla dużych SPA
  • Angażuj się w projekty open source SPA i dziel się swoją wiedzą

🎯 Twój harmonogram opanowania Single-Page Application

timeline
    title Postęp w nauce tworzenia SPA i nowoczesnej architektury webowej
    
    section Podstawy (20 minut)
        Systemy szablonów: Elementy szablonów HTML
                        : Manipulacja DOM
                        : Klonowanie zawartości
                        : Dynamiczne renderowanie
        
    section Podstawy routingu (30 minut)
        Nawigacja po stronie klienta: Zarządzanie URL
                                  : API historii
                                  : Mapowanie tras
                                  : Obsługa zdarzeń
        
    section Doświadczenie użytkownika (40 minut)
        Dopracowanie nawigacji: Integracja z przeglądarką
                             : Obsługa przycisku wstecz
                             : Obsługa błędów
                             : Płynne przejścia
        
    section Wzorce architektury (50 minut)
        Profesjonalne SPA: Systemy komponentów
                         : Zarządzanie stanem
                         : Optymalizacja wydajności
                         : Granice błędów
        
    section Zaawansowane techniki (1 tydzień)
        Integracja frameworków: React Router
                               : Vue Router
                               : Angular Router
                               : Biblioteki stanu
        
    section Umiejętności produkcyjne (1 miesiąc)
        Rozwój korporacyjny: Systemy budowania
                            : Strategie testowania
                            : Procesy wdrażania
                            : Monitorowanie wydajności

🛠️ Podsumowanie Twojego zestawu narzędzi do tworzenia SPA

Po ukończeniu tej lekcji opanowałeś teraz:

  • Architekturę szablonów: wielokrotnego użytku komponenty HTML z dynamicznym renderowaniem zawartości
  • Routing po stronie klienta: zarządzanie URL i nawigację bez przeładowań strony
  • Integrację z przeglądarką: użycie API History i obsługa przycisków wstecz/dalej
  • Systemy zdarzeniowe: obsługa nawigacji i zarządzanie interakcjami użytkownika
  • Manipulację DOM: klonowanie szablonów, przełączanie zawartości oraz zarządzanie elementami
  • Obsługę błędów: eleganckie rozwiązania zapasowe dla błędnych tras i brakującej zawartości
  • Wzorce wydajności: efektywne strategie ładowania i renderowania zawartości

Zastosowania w praktyce: Twoje umiejętności tworzenia SPA mają zastosowanie bezpośrednio w:

  • Nowoczesnych aplikacjach webowych: React, Vue, Angular i inne frameworki
  • Progressive Web Apps: aplikacje działające offline z doświadczeniem aplikacji
  • Dashboardach korporacyjnych: złożone aplikacje biznesowe z wieloma widokami
  • Platformach e-commerce: katalogi produktów, koszyki i procesy zamówień
  • Systemach zarządzania treścią: dynamiczne tworzenie i edycja zawartości
  • Rozwoju mobilnym: aplikacje hybrydowe oparte o technologie webowe

Zdobyte umiejętności zawodowe: Teraz potrafisz:

  • Projektuj aplikacje jednostronicowe z odpowiednim podziałem obowiązków
  • Implementuj systemy routingu po stronie klienta, które skalują się wraz z złożonością aplikacji
  • Debuguj złożone przepływy nawigacji za pomocą narzędzi deweloperskich przeglądarki
  • Optymalizuj wydajność aplikacji poprzez efektywne zarządzanie szablonami
  • Projektuj doświadczenia użytkownika, które są natywne i responsywne

Opanowane koncepcje rozwoju frontendu:

  • Architektura komponentów: wielokrotnego użytku wzorce UI oraz systemy szablonów
  • Synchronizacja stanu: zarządzanie stanem URL i historią przeglądarki
  • Programowanie zdarzeniowe: obsługa interakcji użytkownika oraz nawigacji
  • Optymalizacja wydajności: efektywna manipulacja DOM i ładowanie zawartości
  • Projektowanie doświadczenia użytkownika: płynne przejścia i intuicyjna nawigacja

Kolejny poziom: Jesteś gotowy, aby eksplorować nowoczesne frameworki frontendowe, zaawansowane zarządzanie stanem lub budować złożone aplikacje korporacyjne!

🌟 Osiągnięcie odblokowane: Zbudowałeś profesjonalne fundamenty aplikacji jednostronicowej z nowoczesnymi wzorcami architektury webowej!


Wyzwanie GitHub Copilot Agent 🚀

Użyj trybu Agenta, aby wykonać następujące wyzwanie:

Opis: Rozbuduj aplikację bankową o obsługę błędów i szablon strony 404 dla niepoprawnych tras, poprawiając doświadczenie użytkownika podczas nawigacji do nieistniejących stron.

Podpowiedź: Stwórz nowy szablon HTML o id "not-found", który wyświetla przyjazną dla użytkownika stronę błędu 404 z odpowiednim stylem. Następnie zmodyfikuj logikę routingu w JavaScript, aby wyświetlała ten szablon, gdy użytkownicy przejdą do niepoprawnych URL-i, oraz dodaj przycisk "Idź do domu", który nawiguję z powrotem do strony logowania.

Dowiedz się więcej o trybie agenta.

🚀 Wyzwanie

Dodaj nowy szablon i trasę dla trzeciej strony, która wyświetla informacje o twórcach aplikacji.

Cele wyzwania:

  • Utwórz nowy szablon HTML z odpowiednią strukturą treści
  • Dodaj nową trasę do obiektu konfiguracji tras
  • Uwzględnij linki nawigacyjne do i ze strony z informacjami o twórcach
  • Przetestuj, że cała nawigacja działa poprawnie z historią przeglądarki

Quiz po wykładzie

Quiz po wykładzie

Przegląd i samodzielna nauka

Routing jest jednym z zaskakująco trudnych aspektów tworzenia stron internetowych, zwłaszcza gdy web przechodzi od odświeżania stron do odświeżeń w aplikacjach jednostronicowych. Przeczytaj trochę o tym, jak usługa Azure Static Web App obsługuje routing. Czy potrafisz wyjaśnić, dlaczego niektóre decyzje opisane w tym dokumencie są konieczne?

Dodatkowe materiały do nauki:

  • Poznaj jak popularne frameworki, takie jak React Router i Vue Router, implementują routing po stronie klienta
  • Zbadaj różnice między routingiem opartym na hash i routingiem z użyciem API historii
  • Dowiedz się o renderowaniu po stronie serwera (SSR) i jego wpływie na strategie routingu
  • Zbadaj jak progresywne aplikacje webowe (PWA) radzą sobie z routingiem i nawigacją

Zadanie

Ulepsz routing


Zastrzeżenie:
Dokument ten został przetłumaczony za pomocą usługi tłumaczenia AI Co-op Translator. Pomimo dążenia do dokładności, prosimy mieć na uwadze, że tłumaczenia automatyczne mogą zawierać błędy lub niedokładności. Oryginalny dokument w języku źródłowym powinien być traktowany jako źródło autorytatywne. W przypadku istotnych informacji zalecane jest skorzystanie z profesjonalnego tłumaczenia wykonanego przez człowieka. Nie ponosimy odpowiedzialności za jakiekolwiek nieporozumienia lub błędne interpretacje wynikające z korzystania z tego tłumaczenia.