|
|
7 months ago | |
|---|---|---|
| .. | ||
| README.md | 7 months ago | |
| assignment.md | 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
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:
- Pobranie elementu szablonu w DOM, na przykład za pomocą
document.getElementById. - Sklonowanie elementu szablonu za pomocą
cloneNode. - 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średniotemplateIdjako 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:
- Aktualizację bieżącego URL
- 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
onLinkClickdo 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:
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
popstateze względu na jej zwięzłość, ale zwykła funkcja działałaby tak samo.
Przypomnij sobie wideo o funkcjach strzałkowych:
🎥 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
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
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.

