I have no experience with javascript and typescript. When I used PHP I made a navbar into a function that would echo the html code. Is this also achievable using typescript? I have made a function that returns a string of html code, but I don't know how to actually make it render the html when I call the function on my html page (if the typescript code would even be correct). My school demands that I use typescript.
export function navbar(): string {
const menuItems: MenuItems = {
Home: "index.html",
About: "about.html",
FAQ: "faq.html",
Contact: "contact.html",
};
let htmlCode: string = "<nav><ul>";
for (const [key, value] of Object.entries(menuItems)) {
htmlCode += `<li><a src="${key}">${value}</a></li>`;
}
htmlCode += "</nav></ul>";
return htmlCode;
}
edit: I now have tried this
type MenuItems = {
[key: string]: string;
};
export function createNavbar(): void {
const navigation: HTMLElement = document.createElement("nav");
const unorderedList: HTMLUListElement = document.createElement("ul");
const menuItems: MenuItems = {
Home: "index.html",
About: "about.html",
FAQ: "faq.html",
Contact: "contact.html",
};
for (const [key, value] of Object.entries(menuItems)) {
const listItem: HTMLElement = document.createElement("li");
const anchor: HTMLAnchorElement = document.createElement("a");
anchor.textContent = key;
anchor.href = value;
listItem.appendChild(anchor);
unorderedList.appendChild(listItem);
}
navigation.appendChild(unorderedList);
document.body.appendChild(navigation);
}
and this for my html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="../assets/css/style.css" />
<title>test</title>
</head>
<body>
<script src="../src/common.ts"></script>
<script>createNavbar()</script>
</body>
</html>
it still does not seem to work. I've got a blank page
You're almost there.
There are a handful of ways to buld DOM Fragments but one way is to repeatedly use:
document.createElement() // to create the element before customising it
myParentElement.appendChild(myElement) // appends the new element to its parent
Working Example
const buildNavbar = () => {
const menuItems = {
Home: "index.html",
About: "about.html",
FAQ: "faq.html",
Contact: "contact.html",
};
// BUILD <nav> ELEMENT
const navbarNavigation = document.createElement('nav');
// BUILD <ul> ELEMENT
const navbarUnorderedList = document.createElement('ul');
for (const [key, value] of Object.entries(menuItems)) {
// BUILD <li> ELEMENT
const navbarListItem = document.createElement('li');
// BUILD <a> ELEMENT AND APPEND TO <li> ELEMENT
const navbarAnchor = document.createElement('a');
navbarAnchor.setAttribute('href', value);
navbarAnchor.textContent = key;
navbarListItem.appendChild(navbarAnchor);
// APPEND <li> ELEMENT TO <ul> ELEMENT
navbarUnorderedList.appendChild(navbarListItem);
}
// APPEND <ul> ELEMENT TO <nav> ELEMENT
navbarNavigation.appendChild(navbarUnorderedList);
// APPEND <nav> ELEMENT TO <body> ELEMENT
document.body.appendChild(navbarNavigation);
}
buildNavbar();
N.B. Not uncommonly you'll see approaches which concatenate strings / template literals and then utilise the innerHTML
property, something like this:
const menuItems = {
Home: "index.html",
About: "about.html",
FAQ: "faq.html",
Contact: "contact.html",
};
const navbarNavigation = document.createElement('nav');
let navbarNavigationChildren = '<ul>';
for (const [key, value] of Object.entries(menuItems)) {
navbarNavigationChildren += `<li><a href="${value}">${key}</a></li>`;
}
navbarNavigationChildren += '</ul>';
navbarNavigation.innerHTML = navbarNavigationChildren;
document.appendChild(navbarNavigation);
Which is much closer to how you'd approach the issue in PHP.
However, my own experience is that as you get used to creating DOM Nodes and thinking in those terms, the approach where you build a string of markup and append it via .innerHTML
loses quite a lot of its appeal.
Although popular, the latter approach is something like building JSON via string concatenation and then converting that string into an object via JSON.parse()
, rather than simply... building an object.