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/fi/7-bank-project/1-template-route/README.md

30 KiB

Rakenna pankkisovellus Osa 1: HTML-mallit ja reitit verkkosovelluksessa

Kun Apollo 11:n ohjaustietokone navigoi kuuhun vuonna 1969, sen täytyi vaihtaa ohjelmien välillä ilman, että koko järjestelmä käynnistettiin uudelleen. Modernit verkkosovellukset toimivat samalla tavalla ne muuttavat näytettävää sisältöä ilman, että kaikki ladataan uudelleen alusta. Tämä luo sujuvan ja responsiivisen käyttökokemuksen, jota käyttäjät nykyään odottavat.

Toisin kuin perinteiset verkkosivustot, jotka lataavat koko sivun uudelleen jokaisen vuorovaikutuksen yhteydessä, modernit verkkosovellukset päivittävät vain ne osat, jotka tarvitsevat muutosta. Tämä lähestymistapa, aivan kuten lennonjohto vaihtaa näyttöjä säilyttäen jatkuvan yhteyden, luo sen sulavan kokemuksen, johon olemme tottuneet.

Tässä on syy, miksi ero on niin merkittävä:

Perinteiset monisivuiset sovellukset Modernit yksisivuiset sovellukset
Navigointi Koko sivun lataus jokaiselle näytölle
Suorituskyky Hitaampi, koska HTML ladataan kokonaan
Käyttökokemus Häiritsevät sivun välähdykset
Tietojen jakaminen Vaikeaa sivujen välillä
Kehitys Useita HTML-tiedostoja ylläpidettäväksi

Evoluution ymmärtäminen:

  • Perinteiset sovellukset vaativat palvelinpyyntöjä jokaiselle navigointitoiminnolle
  • Modernit SPA:t latautuvat kerran ja päivittävät sisältöä dynaamisesti JavaScriptin avulla
  • Käyttäjien odotukset suosivat nyt välittömiä, saumattomia vuorovaikutuksia
  • Suorituskykyedut sisältävät pienemmän kaistanleveyden käytön ja nopeammat vastaukset

Tässä oppitunnissa rakennamme pankkisovelluksen, jossa on useita näyttöjä, jotka sulautuvat yhteen saumattomasti. Kuten tiedemiehet käyttävät modulaarisia instrumentteja, joita voidaan konfiguroida eri kokeisiin, käytämme HTML-malleja uudelleenkäytettävinä komponentteina, jotka voidaan näyttää tarpeen mukaan.

Työskentelet HTML-mallien (uudelleenkäytettävät suunnitelmat eri näytöille), JavaScript-reitityksen (järjestelmä, joka vaihtaa näyttöjen välillä) ja selaimen historia-API:n (joka pitää takaisin-painikkeen toiminnassa) kanssa. Nämä ovat samoja perusmenetelmiä, joita käytetään esimerkiksi React-, Vue- ja Angular-kehyksissä.

Lopuksi sinulla on toimiva pankkisovellus, joka demonstroi ammattimaisia yksisivuisen sovelluksen periaatteita.

Ennakkokysely

Ennakkokysely

Mitä tarvitset

Tarvitsemme paikallisen verkkopalvelimen testataksemme pankkisovellustamme älä huoli, se on helpompaa kuin miltä kuulostaa! Jos sinulla ei ole vielä sellaista, asenna Node.js ja suorita npx lite-server projektikansiossasi. Tämä kätevä komento käynnistää paikallisen palvelimen ja avaa sovelluksesi automaattisesti selaimessa.

Valmistelu

Luo tietokoneellesi kansio nimeltä bank ja sen sisälle tiedosto nimeltä index.html. Aloitamme tästä HTML pohjasta:

<!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>

Tämä pohja tarjoaa seuraavaa:

  • Määrittää HTML5-dokumentin rakenteen oikealla DOCTYPE-määrittelyllä
  • Konfiguroi merkistökoodauksen UTF-8:ksi kansainvälisen tekstituen takaamiseksi
  • Mahdollistaa responsiivisen suunnittelun viewport-meta-tagin avulla mobiiliyhteensopivuuden vuoksi
  • Asettaa kuvailevan otsikon, joka näkyy selaimen välilehdessä
  • Luo selkeän body-osan, johon rakennamme sovelluksemme

📁 Projektirakenteen esikatselu

Oppitunnin lopussa projektisi sisältää:

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

Tiedostojen vastuut:

  • index.html: Sisältää kaikki mallit ja tarjoaa sovelluksen rakenteen
  • app.js: Käsittelee reititystä, navigointia ja mallien hallintaa
  • Mallit: Määrittelevät käyttöliittymän kirjautumiselle, hallintapaneelille ja muille näytöille

HTML-mallit

Mallit ratkaisevat perustavanlaatuisen ongelman verkkokehityksessä. Kun Gutenberg keksi irtokirjasimet 1440-luvulla, hän ymmärsi, että sen sijaan, että kaivertaisi kokonaisia sivuja, hän voisi luoda uudelleenkäytettäviä kirjaimia ja järjestää ne tarpeen mukaan. HTML-mallit toimivat samalla periaatteella sen sijaan, että luot erillisiä HTML-tiedostoja jokaiselle näytölle, määrittelet uudelleenkäytettäviä rakenteita, jotka voidaan näyttää tarpeen mukaan.

Ajattele malleja suunnitelmina sovelluksesi eri osille. Aivan kuten arkkitehti luo yhden suunnitelman ja käyttää sitä useita kertoja sen sijaan, että piirtäisi identtisiä huoneita uudelleen, me luomme mallit kerran ja otamme ne käyttöön tarpeen mukaan. Selain pitää nämä mallit piilossa, kunnes JavaScript aktivoi ne.

Jos haluat luoda useita näyttöjä verkkosivulle, yksi ratkaisu olisi luoda yksi HTML-tiedosto jokaiselle näytölle, jonka haluat näyttää. Tämä ratkaisu tuo kuitenkin mukanaan joitakin hankaluuksia:

  • Koko HTML-tiedosto täytyy ladata uudelleen näytön vaihtuessa, mikä voi olla hidasta.
  • Tietojen jakaminen eri näyttöjen välillä on vaikeaa.

Toinen lähestymistapa on käyttää vain yhtä HTML-tiedostoa ja määritellä useita HTML-malleja <template>-elementin avulla. Malli on uudelleenkäytettävä HTML-lohko, jota selain ei näytä, ja joka täytyy ottaa käyttöön ajonaikaisesti JavaScriptin avulla.

Rakennetaan se

Luomme pankkisovelluksen, jossa on kaksi pääasiallista näyttöä: kirjautumissivu ja hallintapaneeli. Aloitetaan lisäämällä paikkamerkki HTML-bodyyn tämä on paikka, jossa kaikki eri näytöt näkyvät:

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

Ymmärrä tämä paikkamerkki:

  • Luo säiliön, jonka ID on "app", ja jossa kaikki näytöt näytetään
  • Näyttää latausviestin, kunnes JavaScript alustaa ensimmäisen näytön
  • Tarjoaa yhden kiinnityspisteen dynaamiselle sisällölle
  • Mahdollistaa helpon kohdistamisen JavaScriptillä käyttämällä document.getElementById()

💡 Vinkki: Koska tämän elementin sisältö korvataan, voimme laittaa siihen latausviestin tai -ilmaisimen, joka näkyy sovelluksen latautuessa.

Seuraavaksi lisätään HTML-malli kirjautumissivulle. Toistaiseksi laitamme siihen vain otsikon ja osion, joka sisältää linkin, jota käytämme navigointiin.

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

Tämän kirjautumismallin erittely:

  • Määrittää mallin, jolla on yksilöllinen tunniste "login" JavaScriptin kohdistamista varten
  • Sisältää pääotsikon, joka luo sovelluksen brändäyksen
  • Sisältää semanttisen <section>-elementin, joka ryhmittelee liittyvän sisällön
  • Tarjoaa navigointilinkin, joka ohjaa käyttäjät hallintapaneeliin

Lisätään sitten toinen HTML-malli hallintapaneelin sivulle. Tämä sivu sisältää eri osioita:

  • Otsikko, jossa on otsikko ja uloskirjautumislinkki
  • Pankkitilin nykyinen saldo
  • Lista tapahtumista, jotka näytetään taulukossa
<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>

Ymmärretään hallintapaneelin osat:

  • Rakentaa sivun semanttisella <header>-elementillä, joka sisältää navigoinnin
  • Näyttää sovelluksen otsikon johdonmukaisesti näytöillä brändäystä varten
  • Tarjoaa uloskirjautumislinkin, joka ohjaa takaisin kirjautumissivulle
  • Näyttää nykyisen tilin saldon omassa osiossaan
  • Järjestää tapahtumatiedot asianmukaisesti rakennetussa HTML-taulukossa
  • Määrittää taulukon otsikot päivämäärälle, kohteelle ja summalle
  • Jättää taulukon rungon tyhjäksi dynaamista sisällön lisäystä varten

💡 Vinkki: Kun luot HTML-malleja, jos haluat nähdä, miltä ne näyttävät, voit kommentoida <template> ja </template>-rivien ympärille <!-- -->.

Miksi luulet, että käytämme id-attribuutteja malleissa? Voisimmeko käyttää jotain muuta, kuten luokkia?

Mallien herättäminen eloon JavaScriptillä

Nyt meidän täytyy tehdä malleista toimivia. Aivan kuten 3D-tulostin ottaa digitaalisen suunnitelman ja luo fyysisen objektin, JavaScript ottaa piilotetut mallit ja luo näkyviä, interaktiivisia elementtejä, joita käyttäjät voivat nähdä ja käyttää.

Prosessi noudattaa kolmea johdonmukaista vaihetta, jotka muodostavat modernin verkkokehityksen perustan. Kun ymmärrät tämän kaavan, tunnistat sen monista kehyksistä ja kirjastoista.

Jos kokeilet nykyistä HTML-tiedostoasi selaimessa, huomaat, että se jää näyttämään Loading.... Tämä johtuu siitä, että meidän täytyy lisätä JavaScript-koodia mallien instanssoimiseksi ja näyttämiseksi.

Mallin instanssointi tehdään yleensä kolmessa vaiheessa:

  1. Haetaan mallielementti DOM:sta, esimerkiksi document.getElementById-metodilla.
  2. Kopioidaan mallielementti cloneNode-metodilla.
  3. Liitetään se DOM:iin näkyvän elementin alle, esimerkiksi appendChild-metodilla.
flowchart TD
    A[🔍 Step 1: Find Template] --> B[📋 Step 2: Clone Template]
    B --> C[🔗 Step 3: Attach to DOM]
    
    A1["document.getElementById('login')"] --> A
    B1["template.content.cloneNode(true)"] --> B  
    C1["app.appendChild(view)"] --> C
    
    C --> D[👁️ Template Visible to User]
    
    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style C fill:#e8f5e8
    style D fill:#fff3e0

Prosessin visuaalinen erittely:

  • Vaihe 1 löytää piilotetun mallin DOM-rakenteesta
  • Vaihe 2 luo toimivan kopion, jota voidaan turvallisesti muokata
  • Vaihe 3 lisää kopion näkyvään sivualueeseen
  • Tuloksena on toimiva näyttö, jonka käyttäjät voivat nähdä ja käyttää

Miksi meidän täytyy kopioida malli ennen sen liittämistä DOM:iin? Mitä luulet tapahtuvan, jos jättäisimme tämän vaiheen väliin?

Tehtävä

Luo uusi tiedosto nimeltä app.js projektikansioosi ja tuo tämä tiedosto HTML-tiedoston <head>-osioon:

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

Ymmärrä tämä skriptin tuonti:

  • Linkittää JavaScript-tiedoston HTML-dokumenttiin
  • Käyttää defer-attribuuttia varmistaakseen, että skripti suoritetaan HTML:n jäsentelyn jälkeen
  • Mahdollistaa pääsyn kaikkiin DOM-elementteihin, koska ne ovat täysin ladattuja ennen skriptin suorittamista
  • Noudattaa moderneja parhaita käytäntöjä skriptin lataamisessa ja suorituskyvyssä

Nyt app.js-tiedostossa luomme uuden funktion nimeltä 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);
}

Vaihe vaiheelta, mitä tapahtuu:

  • Löytää mallielementin sen yksilöllisen ID:n avulla
  • Luo syväkopion mallin sisällöstä käyttämällä cloneNode(true)-metodia
  • Etsii sovellussäiliön, jossa sisältö näytetään
  • Tyhjentää olemassa olevan sisällön sovellussäiliöstä
  • Lisää kopioidun mallisisällön näkyvään DOM:iin

Nyt kutsu tätä funktiota yhdellä mallilla ja katso tulos.

updateRoute('login');

Mitä tämä funktiokutsu tekee:

  • Aktivoi kirjautumismallin välittämällä sen ID:n parametrina
  • Havainnollistaa kuinka ohjelmallisesti vaihdetaan eri sovellusnäyttöjen välillä
  • Näyttää kirjautumisnäytön "Loading..."-viestin tilalla

Mikä on tämän koodin tarkoitus app.innerHTML = '';? Mitä tapahtuu ilman sitä?

Reittien luominen

Reititys tarkoittaa pohjimmiltaan URL-osoitteiden yhdistämistä oikeaan sisältöön. Mieti, kuinka varhaiset puhelinoperaattorit käyttivät kytkentätauluja puheluiden yhdistämiseen he ottivat saapuvan pyynnön ja ohjasivat sen oikeaan kohteeseen. Verkkoreititys toimii samalla tavalla, ottaen URL-pyynnön ja määrittäen, mikä sisältö näytetään.

Perinteisesti verkkopalvelimet hoitivat tämän tarjoamalla eri HTML-tiedostoja eri URL-osoitteille. Koska rakennamme yksisivuista sovellusta, meidän täytyy hoitaa tämä reititys itse JavaScriptillä. Tämä lähestymistapa antaa meille enemmän hallintaa käyttökokemukseen ja suorituskykyyn.

flowchart LR
    A["🌐 URL Path<br/>/dashboard"] --> B["🗺️ Routes Object<br/>Lookup"]
    B --> C["🎯 Template ID<br/>'dashboard'"]
    C --> D["📄 Find Template<br/>getElementById"]
    D --> E["👁️ Display Screen<br/>Clone & Append"]
    
    F["📍 /login"] --> G["🎯 'login'"]
    H["📍 /unknown"] --> I["❌ Not Found"]
    I --> J["🔄 Redirect to /login"]
    
    style B fill:#e3f2fd
    style E fill:#e8f5e8
    style I fill:#ffebee
    style J fill:#fff3e0

Reitityksen kulun ymmärtäminen:

  • URL-muutokset käynnistävät haun reittikonfiguraatiossa
  • Kelvolliset reitit yhdistetään tiettyihin mallien ID-tunnisteisiin
  • Virheelliset reitit käynnistävät varatoiminnon estääkseen virhetilanteet
  • Mallien renderöinti noudattaa aiemmin opittua kolmen vaiheen prosessia

Kun puhumme verkkosovelluksesta, kutsumme reititykseksi tarkoitusta yhdistää URL-osoitteet tiettyihin näyttöihin, jotka pitäisi näyttää. Verkkosivustolla, jossa on useita HTML-tiedostoja, tämä tapahtuu automaattisesti, koska tiedostopolut heijastuvat URL-osoitteeseen. Esimerkiksi, jos projektikansiossasi on nämä tiedostot:

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

Jos luot verkkopalvelimen, jonka juurena on mywebsite, URL-mapping on:

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

Kuitenkin, koska verkkosovelluksemme käyttää yhtä HTML-tiedostoa, joka sisältää kaikki näytöt, tämä oletuskäyttäytyminen ei auta meitä. Meidän täytyy luoda tämä kartta manuaalisesti ja päivittää näytettävä malli JavaScriptin avulla.

Tehtävä

Käytämme yksinkertaista objektia toteuttaaksemme kartoituksen URL-polkujen ja mallien välillä. Lisää tämä objekti app.js-tiedoston alkuun.

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

Ymmärrä tämä reittikonfiguraatio:

  • Määrittää kartoituksen URL-polkujen ja mallien tunnisteiden välillä
  • Käyttää objektisyntaksia, jossa avaimet ovat URL-polkuja ja arvot sisältävät mallien tiedot
  • Mahdollistaa helpon haun siitä, mikä malli näytetään millekin URL-polulle
  • Tarjoaa skaalautuvan rakenteen uusien reittien lisäämiseen tulevaisuudessa

Nyt muokataan hieman updateRoute-funktiota. Sen sijaan, että välitämme suoraan templateId-tunnisteen argumenttina, haluamme ensin tarkistaa nykyisen URL-osoitteen ja käyttää karttaamme saadaksemme vastaavan mallin ID-arvon. Voimme käyttää window.location.pathname-metodia saadaksemme vain polkuosan URL-osoitteesta.

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);
}

Mitä tässä tapahtuu:

  • Hakee nykyisen polun selaimen URL-osoitteesta käyttämällä window.location.pathname

Mitä tapahtuu, jos syötät tuntemattoman polun URL-osoitteeseen? Miten voisimme ratkaista tämän?

Navigoinnin lisääminen

Kun reititys on määritetty, käyttäjien täytyy pystyä navigoimaan sovelluksessa. Perinteiset verkkosivut lataavat kokonaisia sivuja uudelleen linkkejä klikattaessa, mutta me haluamme päivittää sekä URL-osoitteen että sisällön ilman sivun uudelleenlatausta. Tämä luo sujuvamman käyttökokemuksen, joka muistuttaa työpöytäsovellusten näkymien vaihtamista.

Meidän täytyy yhdistää kaksi asiaa: päivittää selaimen URL-osoite, jotta käyttäjät voivat tallentaa sivuja kirjanmerkkeihin ja jakaa linkkejä, sekä näyttää oikea sisältö. Kun tämä toteutetaan oikein, se luo saumattoman navigoinnin, jota käyttäjät odottavat moderneilta sovelluksilta.

🏗️ Arkkitehtuurin näkökulma: Navigointijärjestelmän komponentit

Mitä rakennat:

  • 🔄 URL-hallinta: Päivittää selaimen osoiterivin ilman sivun uudelleenlatausta
  • 📋 Mallijärjestelmä: Vaihtaa sisältöä dynaamisesti nykyisen reitin perusteella
  • 📚 Historia-integraatio: Säilyttää selaimen takaisin/eteenpäin-painikkeiden toiminnallisuuden
  • 🛡️ Virheenkäsittely: Sulavat varajärjestelmät virheellisille tai puuttuville reiteille

Miten komponentit toimivat yhdessä:

  • Kuuntelee navigointitapahtumia (klikkauksia, historiamuutoksia)
  • Päivittää URL-osoitteen History API:n avulla
  • Renderöi oikean mallin uudelle reitille
  • Säilyttää saumattoman käyttökokemuksen

Seuraava askel sovelluksessamme on lisätä mahdollisuus navigoida sivujen välillä ilman, että URL-osoitetta täytyy muuttaa manuaalisesti. Tämä tarkoittaa kahta asiaa:

  1. Päivittää nykyinen URL-osoite
  2. Päivittää näytettävä malli uuden URL-osoitteen perusteella

Olemme jo hoitaneet toisen osan updateRoute-funktiolla, joten meidän täytyy selvittää, miten päivittää nykyinen URL-osoite.

Meidän täytyy käyttää JavaScriptiä ja tarkemmin sanottuna history.pushState, joka mahdollistaa URL-osoitteen päivittämisen ja uuden merkinnän luomisen selaushistoriaan ilman HTML:n uudelleenlatausta.

⚠️ Tärkeä huomautus: Vaikka HTML:n ankkurielementti <a href> voi itsessään luoda hyperlinkkejä eri URL-osoitteisiin, se lataa HTML:n uudelleen oletuksena. Tämä käyttäytyminen täytyy estää, kun käsitellään reititystä mukautetulla JavaScriptillä, käyttämällä preventDefault()-funktiota klikkaustapahtumassa.

Tehtävä

Luodaan uusi funktio, jota voimme käyttää navigointiin sovelluksessamme:

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

Navigointifunktion ymmärtäminen:

  • Päivittää selaimen URL-osoitteen uuteen polkuun käyttäen history.pushState
  • Lisää uuden merkinnän selaimen historiapinoon, jotta takaisin/eteenpäin-painikkeet toimivat oikein
  • Käynnistää updateRoute()-funktion näyttääkseen vastaavan mallin
  • Säilyttää yhden sivun sovelluskokemuksen ilman sivun uudelleenlatausta

Tämä menetelmä päivittää ensin nykyisen URL-osoitteen annetun polun perusteella ja sitten päivittää mallin. Ominaisuus window.location.origin palauttaa URL-juuren, mikä mahdollistaa täydellisen URL-osoitteen rakentamisen annetusta polusta.

Nyt kun meillä on tämä funktio, voimme ratkaista ongelman, joka syntyy, jos polku ei vastaa mitään määriteltyä reittiä. Muokkaamme updateRoute-funktiota lisäämällä varajärjestelmän, joka ohjaa olemassa olevalle reitille, jos vastaavuutta ei löydy.

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);
}

Tärkeät muistettavat asiat:

  • Tarkistaa, onko nykyiselle polulle olemassa reitti
  • Ohjaa kirjautumissivulle, kun virheellinen reitti avataan
  • Tarjoaa varajärjestelmän, joka estää navigoinnin rikkoutumisen
  • Varmistaa, että käyttäjät näkevät aina kelvollisen näkymän, vaikka URL-osoite olisi virheellinen

Jos reittiä ei löydy, ohjaamme nyt login-sivulle.

Luodaan nyt funktio, joka hakee URL-osoitteen, kun linkkiä klikataan, ja estää selaimen oletuslinkkikäyttäytymisen:

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

Klikkauskäsittelijän erittely:

  • Estää selaimen oletuslinkkikäyttäytymisen käyttämällä preventDefault()
  • Hakee kohde-URL-osoitteen klikattavasta linkkielementistä
  • Kutsuu mukautetun navigointifunktion sivun uudelleenlatauksen sijaan
  • Säilyttää sujuvan yhden sivun sovelluskokemuksen
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>

Mitä tämä onclick-sidonta saavuttaa:

  • Yhdistää jokaisen linkin mukautettuun navigointijärjestelmään
  • Välittää klikkaustapahtuman onLinkClick-funktiolle käsittelyä varten
  • Mahdollistaa sujuvan navigoinnin ilman sivun uudelleenlatausta
  • Säilyttää oikean URL-rakenteen, jonka käyttäjät voivat tallentaa kirjanmerkkeihin tai jakaa

onclick-attribuutti sitoo click-tapahtuman JavaScript-koodiin, tässä kutsuun navigate()-funktiolle.

Kokeile klikata näitä linkkejä, nyt pitäisi olla mahdollista navigoida sovelluksen eri näkymien välillä.

history.pushState-menetelmä on osa HTML5-standardia ja toteutettu kaikissa moderneissa selaimissa. Jos rakennat verkkosovellusta vanhemmille selaimille, voit käyttää tämän API:n sijasta kikkaa: käyttämällä hash-merkkiä (#) ennen polkua voit toteuttaa reitityksen, joka toimii tavallisella ankkurinavigoinnilla eikä lataa sivua uudelleen, sillä sen tarkoitus oli luoda sisäisiä linkkejä sivun sisällä.

Takaisin- ja eteenpäin-painikkeiden toiminnan varmistaminen

Takaisin- ja eteenpäin-painikkeet ovat olennainen osa verkkoselaamista, aivan kuten NASA:n ohjauskeskus voi tarkastella aiempia järjestelmän tiloja avaruuslentoja varten. Käyttäjät odottavat näiden painikkeiden toimivan, ja jos ne eivät toimi, se rikkoo odotettua selauskokemusta.

Yhden sivun sovelluksemme tarvitsee lisäkonfiguraatiota tukeakseen tätä. Selaimen historiapino (johon olemme lisänneet merkintöjä history.pushState-menetelmällä) täytyy päivittää, mutta kun käyttäjät navigoivat tämän historian läpi, sovelluksemme täytyy reagoida päivittämällä näytettävä sisältö vastaavasti.

sequenceDiagram
    participant User
    participant Browser
    participant App
    participant Template
    
    User->>Browser: Clicks "Login" link
    Browser->>App: onclick event triggered
    App->>App: preventDefault() & navigate('/dashboard')
    App->>Browser: history.pushState('/dashboard')
    Browser->>Browser: URL updates to /dashboard
    App->>App: updateRoute() called
    App->>Template: Find & clone dashboard template
    Template->>App: Return cloned content
    App->>Browser: Replace app content with template
    Browser->>User: Display dashboard screen
    
    Note over User,Template: User clicks browser back button
    
    User->>Browser: Clicks back button
    Browser->>Browser: History moves back to /login
    Browser->>App: popstate event fired
    App->>App: updateRoute() called automatically
    App->>Template: Find & clone login template
    Template->>App: Return cloned content
    App->>Browser: Replace app content with template
    Browser->>User: Display login screen

Keskeiset vuorovaikutuspisteet:

  • Käyttäjän toiminnot käynnistävät navigoinnin klikkauksilla tai selaimen painikkeilla
  • Sovellus sieppaa linkkiklikkaukset estääkseen sivun uudelleenlatauksen
  • Historia-API hallitsee URL-muutoksia ja selaimen historiapinoa
  • Mallit tarjoavat sisältörakenteen jokaiselle näkymälle
  • Tapahtumakuuntelijat varmistavat, että sovellus reagoi kaikkiin navigointityyppeihin

history.pushState-menetelmän käyttö luo uusia merkintöjä selaimen navigointihistoriaan. Voit tarkistaa tämän pitämällä selaimen takaisin-painiketta painettuna, jolloin sen pitäisi näyttää jotain tällaista:

Navigointihistorian kuvakaappaus

Jos yrität klikata takaisin-painiketta muutaman kerran, huomaat, että nykyinen URL-osoite muuttuu ja historia päivittyy, mutta sama malli pysyy näkyvissä.

Tämä johtuu siitä, että sovellus ei tiedä, että meidän täytyy kutsua updateRoute() aina, kun historia muuttuu. Jos tarkastelet history.pushState-dokumentaatiota, näet, että kun tila muuttuu - eli siirrymme eri URL-osoitteeseen - popstate-tapahtuma käynnistyy. Käytämme tätä korjataksemme ongelman.

Tehtävä

Jotta näytettävä malli päivittyy, kun selaimen historia muuttuu, liitämme uuden funktion, joka kutsuu updateRoute()-funktiota. Teemme tämän app.js-tiedoston loppuun:

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

Historiaintegration ymmärtäminen:

  • Kuuntelee popstate-tapahtumia, jotka tapahtuvat, kun käyttäjät navigoivat selaimen painikkeilla
  • Käyttää nuolifunktiota tiiviiseen tapahtumakäsittelijän syntaksiin
  • Kutsuu updateRoute() automaattisesti aina, kun historiatila muuttuu
  • Alustaa sovelluksen kutsumalla updateRoute()-funktiota, kun sivu latautuu ensimmäistä kertaa
  • Varmistaa, että oikea malli näkyy riippumatta siitä, miten käyttäjät navigoivat

💡 Vinkki: Käytimme nuolifunktiota popstate-tapahtumakäsittelijän määrittämiseen tiiviyden vuoksi, mutta tavallinen funktio toimisi samalla tavalla.

Tässä on video nuolifunktioista:

Nuolifunktiot

🎥 Klikkaa yllä olevaa kuvaa katsoaksesi videon nuolifunktioista.

Kokeile nyt käyttää selaimesi takaisin- ja eteenpäin-painikkeita ja tarkista, että näytettävä reitti päivittyy tällä kertaa oikein.


GitHub Copilot Agent -haaste 🚀

Käytä Agent-tilaa suorittaaksesi seuraavan haasteen:

Kuvaus: Paranna pankkisovellusta toteuttamalla virheenkäsittely ja 404-sivumalli virheellisille reiteille, parantaen käyttäjäkokemusta navigoidessa olemattomiin sivuihin.

Tehtävä: Luo uusi HTML-malli id:llä "not-found", joka näyttää käyttäjäystävällisen 404-virhesivun tyylittelyineen. Muokkaa sitten JavaScript-reitityslogiikkaa näyttämään tämä malli, kun käyttäjät navigoivat virheellisiin URL-osoitteisiin, ja lisää "Mene kotiin" -painike, joka ohjaa takaisin kirjautumissivulle.

Lisätietoja Agent-tilasta täällä.

🚀 Haaste

Lisää uusi malli ja reitti kolmannelle sivulle, joka näyttää tämän sovelluksen tekijätiedot.

Haasteen tavoitteet:

  • Luo uusi HTML-malli, jossa on asianmukainen sisältörakenne
  • Lisää uusi reitti reittikonfiguraatio-objektiisi
  • Sisällytä navigointilinkit tekijätiedot-sivulle ja sieltä pois
  • Testaa, että kaikki navigointi toimii oikein selaimen historiassa

Luentojälkeinen kysely

Luentojälkeinen kysely

Kertaus ja itseopiskelu

Reititys on yksi yllättävän haastavista verkkokehityksen osa-alueista, erityisesti kun verkkosivut siirtyvät sivun uudelleenlatauskäyttäytymisestä yhden sivun sovellusten päivityksiin. Lue hieman Azure Static Web App -palvelun reitityksen käsittelystä. Voitko selittää, miksi jotkut dokumentissa kuvatut päätökset ovat välttämättömiä?

Lisäoppimateriaalit:

  • Tutki, miten suositut kehykset kuten React Router ja Vue Router toteuttavat asiakaspuolen reitityksen
  • Tutki, hash-pohjaisen reitityksen ja History API -reitityksen erot
  • Opi, mitä palvelinpuolen renderöinti (SSR) on ja miten se vaikuttaa reititysstrategioihin
  • Tutki, miten Progressiiviset verkkosovellukset (PWA:t) käsittelevät reititystä ja navigointia

Tehtävä

Paranna reititystä


Vastuuvapauslauseke:
Tämä asiakirja on käännetty käyttämällä tekoälypohjaista käännöspalvelua Co-op Translator. Vaikka pyrimme tarkkuuteen, huomioithan, että automaattiset käännökset voivat sisältää virheitä tai epätarkkuuksia. Alkuperäinen asiakirja sen alkuperäisellä kielellä tulisi pitää ensisijaisena lähteenä. Kriittisen tiedon osalta suositellaan ammattimaista ihmiskäännöstä. Emme ole vastuussa väärinkäsityksistä tai virhetulkinnoista, jotka johtuvat tämän käännöksen käytöstä.