Skip to content

Instantly share code, notes, and snippets.

@JBreit
Last active June 16, 2018 12:08
Show Gist options
  • Save JBreit/7ae2dfa8277d03ecde03727a15acadc7 to your computer and use it in GitHub Desktop.
Save JBreit/7ae2dfa8277d03ecde03727a15acadc7 to your computer and use it in GitHub Desktop.
{
"routes": {
"index": {
"title": "Home Page",
"content": "This is the homepage."
},
"list": {
"title": "List Page",
"content": "List Page content."
}
}
}
/* global window document fetch history */
const links = document.querySelectorAll('.route');
const titleElement = document.getElementById('title');
const contentElement = document.getElementById('content');
const defaultRoute = 'index';
const handleError = (err) => {
return console.error(err);
};
const update = (model) => {
if (model) {
document.title = model.title;
titleElement.innerHTML = model.title;
contentElement.innerHTML = model.content;
}
};
if (window.fetch && window.history && window.addEventListener) {
const fetchData = () => {
return fetch('/data.json')
.then((response) => {
if (response.status === 200) {
if (response.headers.get('Content-Type') === 'application/json') {
return response.json();
}
}
})
.catch(err => handleError);
};
const handleClickEvent = (event) => {
event.preventDefault();
const href = event.target.attributes[0].value;
const route = href.substring(1) || defaultRoute;
fetchData()
.then((data) => {
const state = data.routes[route];
update(state);
history.pushState(state, state.title, href);
})
.catch(err => handleError);
};
links.forEach(link => link.addEventListener('click', handleClickEvent, false));
const handlePopstateEvent = (event) => {
const state = event.state;
update(state);
};
window.addEventListener('popstate', handlePopstateEvent, false);
const handleLoadEvent = (event) => {
if (location.pathname === '/') {
fetchData()
.then((data) => {
const state = data.routes[defaultRoute];
update(state);
history.replaceState(state, state.title, '/');
})
.catch(err => handleError);
}
};
document.addEventListener('DOMContentLoaded', handleLoadEvent, false);
} else {
console.log('fetch api not supported in legacy browsers IE <= 10');
}
<!DOCTYPE html>
<html lang="en-us">
<head>
<base href="/">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Jason Breitigan">
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="assets/img/apple-touch-icon-57x57.png" />
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/img/apple-touch-icon-114x114.png" />
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/img/apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/img/apple-touch-icon-144x144.png" />
<link rel="apple-touch-icon-precomposed" sizes="60x60" href="assets/img/apple-touch-icon-60x60.png" />
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="assets/img/apple-touch-icon-120x120.png" />
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="assets/img/apple-touch-icon-76x76.png" />
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="assets/img/apple-touch-icon-152x152.png" />
<link rel="icon" type="image/png" href="assets/img/favicon-196x196.png" sizes="196x196" />
<link rel="icon" type="image/png" href="assets/img/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/png" href="assets/img/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="assets/img/favicon-16x16.png" sizes="16x16" />
<link rel="icon" type="image/png" href="assets/img/favicon-128.png" sizes="128x128" />
<meta name="application-name" content="&nbsp;"/>
<meta name="msapplication-TileColor" content="#FFFFFF" />
<meta name="msapplication-TileImage" content="assets/img/mstile-144x144.png" />
<meta name="msapplication-square70x70logo" content="assets/img/mstile-70x70.png" />
<meta name="msapplication-square150x150logo" content="assets/img/mstile-150x150.png" />
<meta name="msapplication-wide310x150logo" content="assets/img/mstile-310x150.png" />
<meta name="msapplication-square310x310logo" content="assets/img/mstile-310x310.png" />
<link rel="icon" href="assets/img/favicon.ico">
<title>Dev Environment</title>
<link rel="stylesheet" type="text/css" href="lib/vendor/normalize.css/normalize.css" />
<link rel="stylesheet" type="text/css" href="lib/vendor/Font-Awesome/css/font-awesome.min.css" />
<link rel="stylesheet" type="text/css" href="assets/css/main.css">
</head>
<body>
<div id="app-root" role="app">
<header id="masthead">
<a href="/">Todo App</a>
</header>
<nav id="app-router" role="router">
<a href="/" class="route">Home</a>
<a href="/list" class="route">List</a>
</nav>
<main role="main">
<div role="page">
<h1 id="title"></h1>
<section id="content"></section>
</div>
</main>
<footer></footer>
</div>
<script src="assets/js/history-api.js"></script>
</body>
</html>
* {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
:root {
font-size: 16px;
}
html,
body {
height: 100%;
width: 100%;
overflow: hidden;
}
body {
background: #fff;
margin: 0 auto;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment