Skip to content

Instantly share code, notes, and snippets.

@karolk
Created July 27, 2015 22:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save karolk/d3df1993d5bf9d6b1514 to your computer and use it in GitHub Desktop.
Save karolk/d3df1993d5bf9d6b1514 to your computer and use it in GitHub Desktop.
mini spa
<!doctype html>
<script>
function $(selector) {
return document.querySelectorAll(selector)
}
function onClick(selector, callback) {
$("html")[0].addEventListener("click", function(event) {
if (event.target.matches(selector)) {
callback.call(event.target, event)
}
})
}
var navigationCallbacks = {}
addEventListener("popstate", function(state) {
if (history.state && history.state.path in navigationCallbacks) {
navigationCallbacks[history.state.path]()
}
})
function onNavigate(path, callback) {
navigationCallbacks[path] = callback
}
function navigate(path) {
if (path in navigationCallbacks) {
history.pushState({path: path}, "", path)
navigationCallbacks[path]()
}
}
function render(selector, templateSelector, context) {
var templateSource = $(templateSelector)[0].innerHTML
var templateFunction = new Function("context", "return `" + templateSource + "`")
$(selector)[0].innerHTML = templateFunction(context)
}
function init() {
onClick("a", function(event) {
navigate(this.getAttribute("href"))
event.preventDefault()
})
navigate(location.pathname)
}
</script>
<body>
<a href="/gate-1">Open gate 1</a>
<a href="/gate-2">Open gate 2</a>
<a href="/gate-3">Open gate 3</a>
<main>
</main>
<template id="view0">
<p>Hello ${context.name}</p>
</template>
<template id="view1">
<p>Your prize is <strong>${context.prize}</strong></p>
<a href="/">Go back</a>
</template>
<script>
onNavigate("/", function() {
render("main", "#view0", {name: "Anonymous"})
})
onNavigate("/gate-1", function() {
render("main", "#view1", {prize: "Goat"})
})
onNavigate("/gate-2", function() {
render("main", "#view1", {prize: "*** Gold ***"})
})
onNavigate("/gate-3", function() {
render("main", "#view1", {prize: "Goat"})
})
init()
</script>
</body>
/* Use the server by running `node server.js`
the purpose is for the server to always return index.html
no matter what the path is */
var server = require("http")
var filesys = require("fs")
server.createServer(function(request,response){
filesys.readFile("index.html", function(err, data) { 
response.writeHeader(200)
response.write(data)
response.end()
})
}).listen(8080)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment