constpages={'home':`
<div class="home">
<h1>Welcome to the Fletcher Flyer </h1>
<br>
This is a blog by me, Fletcher the dog. <br>
My mom thought it was about time I have my own site
<br>to share my adventures and offer my services.
<br>
<br>
Unlike the Disney hit show "Dog with a Blog", I cannot talk.
<br>
But I do have remarkable typing skills, soulful eyes,<br> and an eye for hats.
<br>
</div>`,'about':` <h1>About Page</h1><br>`,'contacts':` <h1>ContactsPage</h1><br>`}constgetPageContent=(page='home')=>document.getElementById('content').innerHTML=pages[page]document.addEventListener("DOMContentLoaded",()=>getPageContent());
(function(){constHOME_TEMPLATE=makeTemplate(`<div class="home">
<h1>Welcome to the Fletcher Flyer </h1>
<br>
This is a blog by me, Fletcher the dog. <br>
My mom thought it was about time I have my own site
<br>to share my adventures and offer my services.
<br>
<br>
Unlike the Disney hit show "Dog with a Blog", I cannot talk.
<br>
But I do have remarkable typing skills, soulful eyes,<br> and an eye for hats.
<br>
</div>`);constABOUT_TEMPLATE=makeTemplate(`<h1>About Page</h1><br>`);constCONTACTS_TEMPLATE=makeTemplate(`<h1>ContactsPage</h1><br>`);constDEFAULT_TEMPLATE='home';consttemplates={home:HOME_TEMPLATE,about:ABOUT_TEMPLATE,contacts:CONTACTS_TEMPLATE,};functionmakeTemplate(htmlText){consttemplate=document.createElement('template');template.innerHTML=htmlText;returntemplate;}functiongetTemplate(page){constkey=Object.hasOwn(templates,page)?page:DEFAULT_TEMPLATE;returntemplates[key];}functionloadPageContent(){constclone=getTemplate(DEFAULT_TEMPLATE).content.cloneNode(true);document.getElementById('content').replaceChildren(clone);}if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',loadPageContent);}else{loadPageContent();}})();
Note that HTML inline event handlers will be blocked under a strict Content Security Policy (CSP).
They represent legacy DOM Level 0 event handling.
The historical counter arguments often miss that the environment a DOM level 0 event handler executes in can get extremely weird, leading to all sorts of surprising bugs.
Clicking the button will log false in the console even though there is no such variable - only there is. Switching to the debugger it becomes clear that the handler executes within three nested with statements, one each for the document, form, and button practically polluting the handler's scope with the properties of each of those elements as variables; so disabled belongs to button.
Maybe you don't even need to use the switch
The
switch
is implemented with adefault
in case there is no matching page name, so…With template elements the HTML strings only have to be parsed once (and the templates could simply reside within the HTML).
Object.hasOwn()
HTMLTemplateElement.content
Node.cloneNode()
Element.replaceChildren()
DOMContentLoaded
eventNote that HTML inline event handlers will be blocked under a strict Content Security Policy (CSP).
They represent legacy DOM Level 0 event handling.
The historical counter arguments often miss that the environment a DOM level 0 event handler executes in can get extremely weird, leading to all sorts of surprising bugs.
For example:
Clicking the button will log
false
in the console even though there is no such variable - only there is. Switching to the debugger it becomes clear that the handler executes within three nestedwith
statements, one each for thedocument
,form
, andbutton
practically polluting the handler's scope with the properties of each of those elements as variables; sodisabled
belongs tobutton
.For more details see: Unsafe Names for HTML Form Controls - Event Handler Scope
So the MDN's advice is:
"You should never use the HTML event handler attributes — those are outdated, and using them is bad practice."
That's still not necessary, as you can check if your page is in pages and otherwise return home (or a 404 page):
FYI:
"Note:
Object.hasOwn()
is recommended overhasOwnProperty()
, in browsers where it is supported."Thanks for pointing that out!!