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!