Toepassingsroutering op één pagina met hash of URL

Een van de meest gestelde codevragen tijdens een front-end interview is:"Kun je een applicatie met één pagina maken met routes, zonder raamwerk?" In deze zelfstudie laat ik u zien hoe u een aangepast routeringssysteem voor uw toepassing met één pagina kunt maken met behulp van de hash- of URL-methode... zonder raamwerk.

Deze tutorial laat zien hoe je een Single Page App bouwt met vanilla JavaScript. Ik laat u zien hoe u routering aan de clientzijde in beide richtingen (hash of URL) kunt implementeren in een gebruiksvriendelijke indeling die voor elk project kan worden gerepliceerd.

Bekijk dit op YouTube

Mappenstructuur

We gebruiken een eenvoudige HTML-structuur. Je kunt je bestanden instellen zoals je wilt, maar omwille van deze tutorial kun je repliceren wat ik hieronder heb.

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

Laten we onze HTML maken

We gaan een eenvoudig HTML-document maken om als hoofdpagina te dienen. Op deze pagina hebben we een navigatiegedeelte en een inhoudsgedeelte. Je kunt dit uitbouwen zoals je wilt, maar let op de <nav></nav> tags worden gebruikt voor URL-routering, dus uw navigatie moet aanwezig zijn binnen die tags als u de URL-methode gebruikt.

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

Het JS-bestand maken

Voor de </body> sluitingstag, moet u deze verwijzing toevoegen aan het JS-bestand dat u hierboven hebt gemaakt.

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

Optie één:URL-routering

Eerst gaan we bespreken hoe u dit kunt doen met URL-routing . Dit betekent dat uw links eruit zullen zien als /about . Dit is het typische uiterlijk van een URL. de hash-methode gebruikt # om de pagina's op te splitsen. Ik zal dat verderop bespreken.

Gebruiksvoorbeeld:websites

Deze optie is beter voor SEO en is gebruiksvriendelijker.

OPMERKING: Er zijn enkele nadelen aan het gebruik van deze methode. U moet de webserver configureren om de index.html voor SPA-routepaden te dienen. U kunt dit op serverniveau doen, maar als u iets als VS Code LIVE SERVER gebruikt, kunt u dat niet. Dit betekent dat als u rechtstreeks naar /about navigeert, de server het bestand niet zal renderen omdat het eerst de index.html-scripts moet laden. U kunt uw .htaccess-bestand wijzigen om dit te bereiken.

Voeg de HTML-navigatie toe

Voeg het volgende toe tussen de <nav></nav> tags in uw index.html-bestand.

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

Voeg de navigatielinks toe in HTML

Laten we nu beginnen met de JS. Eerst willen we een link maken in de <nav></nav> tags gebruiken onze 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();
});

Maak de routes

Elke route heeft een bijbehorende objectarray. Dit vertelt het script wat de URL-referentie is, evenals welke sjabloon, titel en beschrijving moeten worden gebruikt.

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",
    },
};

Maak een functie die de URL bekijkt en de urlLocationHandler aanroept

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

Maak een functie die de URL-locatie afhandelt

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

Het script afmaken

Ten slotte moeten we de functie aanroepen wanneer de pagina voor het eerst wordt geladen, anders werkt de startpagina niet tenzij erop wordt geklikt. We moeten ook een watcher toevoegen voor de URL-wijzigingen, zodat het script weet wanneer nieuwe inhoud moet worden weergegeven.

// 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();

Optie twee:hash-routing

Vervang de inhoud van uw router.js-bestand door de volgende code als u de hash-methode gebruikt.

Nu, op naar de tweede optie. Hash-routing komt vaker voor als u een framework gebruikt, maar als u het helemaal opnieuw maakt, kan het negatieve SEO-voordeel u terugschrikken. Dit betekent dat uw links eruit zullen zien als #about in plaats van de typische URL-methode hierboven. Voor sommigen is dit URL-type mogelijk niet optimaal omdat het zo anders is dan wat uw gebruikers gewend zijn. Anders lijkt de code erg op de URL-methode... zelfs korter.

Gebruiksvoorbeeld:apps, bestemmingspagina's

OPMERKING: Er zijn enkele nadelen aan het gebruik van deze methode. hashes zingen is misschien niet de beste route voor SEO en het kan ook ongebruikelijk zijn voor sommige gebruikers, waardoor ze de website mogelijk niet gebruiken.

Voeg de HTML-navigatie toe

Voeg het volgende toe tussen de <nav></nav> tags in uw index.html-bestand.

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

Maak de routes

De hash-routes lijken erg op de bovenstaande URL-routes. U kunt dit deel van het script opnieuw gebruiken. Het verschil zit hem vooral in de manier waarop de routelinksleutel is gedefinieerd.

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",
    },
};

Maak een functie die de URL-locatie afhandelt

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

Het script afmaken

Nogmaals, we moeten de functie aanroepen wanneer de pagina voor het eerst wordt geladen, anders werkt de startpagina niet tenzij erop wordt geklikt. We moeten ook een watcher toevoegen voor de hash-wijzigingen, zodat het script weet wanneer nieuwe inhoud moet worden weergegeven.

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

Conclusie

Dus hoewel er veel manieren zijn om dit te doen, zijn dit de 2 die je moet weten om je een betere frontend-ontwikkelaar te maken. Zodra u deze kent, kunt u doorgaan naar React- of Vue-frameworks. Dus hopelijk hebben deze eenvoudige maar cruciale leermethoden je geholpen om die gevreesde interviewvraag aan het begin van het artikel te doorstaan. veel succes!