JavaScript >> Javascript tutorial >  >> Tags >> URL

Enkeltsideapplikationsrouting ved hjælp af hash eller URL

Et af de mest stillede kodespørgsmål under et frontend-interview er "Kan du oprette en enkeltsideapplikation med ruter uden rammer?" I denne vejledning viser jeg dig, hvordan du opretter et brugerdefineret routingsystem til din enkeltsideapplikation ved hjælp af enten hash- eller URL-metoden...uden en ramme.

Denne vejledning viser dig, hvordan du bygger en enkeltside-app ved hjælp af vanilla JavaScript. Jeg viser dig, hvordan du implementerer routing på klientsiden begge veje (hash eller URL) i et brugervenligt format, der kan replikeres til ethvert projekt.

Se dette på YouTube

Mappestruktur

Vi bruger en grundlæggende HTML-struktur. Du kan konfigurere dine filer, som du vil, men af ​​hensyn til denne vejledning kan du replikere, hvad jeg har nedenfor.

index.html
/templates
   404.html
   index.html
   about.html
   contact.html
/js/
   router.js

Lad os skabe vores HTML

Vi vil oprette et grundlæggende HTML-dokument, der skal fungere som hovedsiden. På denne side vil vi have en nav-sektion og en indholdssektion. Du kan bygge dette ud, som du vil, men bemærk <nav></nav> tags bruges til URL-routing, så din nav skal være til stede i disse tags, hvis du går efter URL-metoden.

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title></title>
   </head>
   <body>
      <nav>
      </nav>
      <div id="content"></div>
   </body>
</html>

Oprettelse af JS-filen

Før </body> afsluttende tag, skal du tilføje denne reference til den JS-fil, du oprettede ovenfor.

<script src="/js/router.js"></script>

Mulighed 1:URL-routing

Først skal vi gennemgå, hvordan man gør dette med URL-routing . Det betyder, at dine links vil se ud som /about . Dette er det typiske udseende af en URL. hash-metoden bruger # at bryde siderne op. Jeg vil gennemgå det længere nede.

Use Case:Websites

Denne mulighed er bedre til SEO og er mere brugervenlig.

BEMÆRK: Der er nogle ulemper ved at bruge denne metode. Du skal konfigurere webserveren til at betjene index.html for SPA-rutestier. Du kan gøre dette på serverniveau, men hvis du bruger noget som VS Code LIVE SERVER, kan du ikke. Dette betyder, at hvis du navigerer direkte til /om, vil serveren ikke gengive filen, da den skal indlæse index.html scripts først. Du kan ændre din .htaccess-fil for at opnå dette.

Tilføj HTML-navigationen

Tilføj følgende mellem <nav></nav> tags i din index.html fil.

<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>

Tilføj navigationslinks i HTML

Lad os nu komme i gang med JS. Først vil vi lave et hvilket som helst link i <nav></nav> tags bruger vores routing.

// create document click that watches the nav links only
document.addEventListener("click", (e) => {
    const { target } = e;
    if (!target.matches("nav a")) {
        return;
    }
    e.preventDefault();
    route();
});

Opret ruterne

Hver rute vil have et objektarray tilknyttet. Dette vil fortælle scriptet, hvad URL-referencen er, samt hvilken skabelon, titel og beskrivelse, der skal bruges.

const routes = {
    404: {
        template: "/templates/404.html",
        title: "404",
        description: "Page not found",
    },
    "/": {
        template: "/templates/index.html",
        title: "Home",
        description: "This is the home page",
    },
    "/about": {
        template: "/templates/about.html",
        title: "About Us",
        description: "This is the about page",
    },
    "/contact": {
        template: "/templates/contact.html",
        title: "Contact Us",
        description: "This is the contact page",
    },
};

Opret en funktion, der overvåger URL'en og kalder urlLocationHandler

const route = (event) => {
    event = event || window.event; // get window.event if event argument not provided
    event.preventDefault();
    // window.history.pushState(state, unused, target link);
    window.history.pushState({}, "", event.target.href);
    locationHandler();
};

Opret en funktion, der håndterer URL-placeringen

const locationHandler = async () => {
    const location = window.location.pathname; // get the url path
    // if the path length is 0, set it to primary page route
    if (location.length == 0) {
        location = "/";
    }
    // get the route object from the urlRoutes object
    const route = routes[location] || routes["404"];
    // get the html from the template
    const html = await fetch(route.template).then((response) => response.text());
    // set the content of the content div to the html
    document.getElementById("content").innerHTML = html;
    // set the title of the document to the title of the route
    document.title = route.title;
    // set the description of the document to the description of the route
    document
        .querySelector('meta[name="description"]')
        .setAttribute("content", route.description);
};

Afslutning af scriptet

Til sidst skal vi kalde funktionen, når siden først indlæses, ellers vil hjemmesiden ikke fungere, medmindre der klikkes på den. Vi skal også tilføje en overvåger for URL-ændringerne, så scriptet ved, hvornår det skal vise nyt indhold.

// add an event listener to the window that watches for url changes
window.onpopstate = locationHandler;
// call the urlLocationHandler function to handle the initial url
window.route = route;
// call the urlLocationHandler function to handle the initial url
locationHandler();

Mulighed to:Hash-routing

Erstat venligst indholdet af din router.js-fil med følgende kode, hvis du bruger hash-metoden.

Nu til den anden mulighed. Hash-routing er mere almindelig, hvis du bruger et framework, men hvis du opretter det fra bunden, kan den negative SEO-fordel få dig til at vige tilbage. Det betyder, at dine links vil se ud som #about i stedet for den typiske URL-metode ovenfor. For nogle er denne URL-type muligvis ikke optimal, fordi den er så anderledes end hvad dine brugere er vant til. Ellers minder koden meget om URL-metoden...endnu kortere.

Use Case:Apps, Landingssider

BEMÆRK: Der er nogle ulemper ved at bruge denne metode. synge hash er muligvis ikke den bedste vej til SEO, og det kan også være usædvanligt for nogle brugere, hvilket kan få dem til ikke at bruge webstedet.

Tilføj HTML-navigationen

Tilføj følgende mellem <nav></nav> tags i din index.html fil.

<a href="/">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>

Opret ruterne

Hash-ruterne ligner meget URL-ruterne ovenfor. Du kan genbruge denne del af scriptet. Forskellen er hovedsageligt, hvordan rutelinknøglen er defineret.

const routes = {
    404: {
        template: "/templates/404.html",
        title: "404",
        description: "Page not found",
    },
    "/": {
        template: "/templates/index.html",
        title: "Home",
        description: "This is the home page",
    },
    about: {
        template: "/templates/about.html",
        title: "About Us",
        description: "This is the about page",
    },
    contact: {
        template: "/templates/contact.html",
        title: "Contact Us",
        description: "This is the contact page",
    },
};

Opret en funktion, der håndterer URL-placeringen

const locationHandler = async () => {
    // get the url path, replace hash with empty string
    var location = window.location.hash.replace("#", "");
    // if the path length is 0, set it to primary page route
    if (location.length == 0) {
        location = "/";
    }
    // get the route object from the routes object
    const route = routes[location] || routes["404"];
    // get the html from the template
    const html = await fetch(route.template).then((response) => response.text());
    // set the content of the content div to the html
    document.getElementById("content").innerHTML = html;
    // set the title of the document to the title of the route
    document.title = route.title;
    // set the description of the document to the description of the route
    document
        .querySelector('meta[name="description"]')
        .setAttribute("content", route.description);
};

Afslutning af scriptet

Igen skal vi kalde funktionen, når siden først indlæses, ellers vil hjemmesiden ikke fungere, medmindre der klikkes på den. Vi skal også tilføje en overvåger for hash-ændringerne, så scriptet ved, hvornår det skal vise nyt indhold.

// create a function that watches the hash and calls the urlLocationHandler
window.addEventListener("hashchange", locationHandler);
// call the urlLocationHandler to load the page
locationHandler();

Konklusion

Så selvom der er mange måder at gøre dette på, er det de 2, du skal kende for at gøre dig til en bedre frontend-udvikler. Når du kender disse, kan du gå videre til React eller Vue frameworks. Så forhåbentlig hjalp disse enkle, men afgørende læringsmetoder dig med at bestå det frygtede interviewspørgsmål i begyndelsen af ​​artiklen. held og lykke!