Created
August 4, 2017 17:24
-
-
Save fr0gs/133127ce31d73e7010ef19db874c319b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//ROUTER | |
//Silly small javascript router to help me learn how they worked in a very simple way | |
(function (){ | |
const appDiv = "app"; | |
// Both set of different routes and template generation functions | |
let routes = {}; | |
let templates = {}; | |
// Generate DOM tree from a string | |
let createDiv = (id, xmlString) => { | |
let d = document.createElement('div'); | |
d.id = id; | |
d.innerHTML = xmlString; | |
return d.firstChild; | |
}; | |
// Register a template (this is to mimic a template engine) | |
let template = (name, templateFunction) => { | |
return templates[name] = templateFunction; | |
}; | |
// Define the routes. Each route is described with a route path & a template to render | |
// when entering that path. A template can be a string (file name), or a function that | |
// will directly create the DOM objects. | |
let route = (path, template) => { | |
if (typeof template == "function") { | |
return routes[path] = template; | |
} | |
else if (typeof template == "string") { | |
return routes[path] = templates[template]; | |
} | |
else { | |
return; | |
} | |
}; | |
// Give the correspondent route (template) or fail | |
let resolveRoute = (route) => { | |
try { | |
return routes[route]; | |
} catch (error) { | |
throw new Error("The route is not defined"); | |
} | |
}; | |
// The actual router, get the current URL and generate the corresponding template | |
let router = (evt) => { | |
const url = window.location.hash.slice(1) || "/"; | |
const routeResolved = resolveRoute(url); | |
routeResolved(); | |
}; | |
// Helper function to create a link. | |
let createLink = (title, text, href) => { | |
let a = document.createElement('a'); | |
let linkText = document.createTextNode(text); | |
a.appendChild(linkText); | |
a.title = title; | |
a.href = href; | |
return a; | |
}; | |
// Register the templates. | |
template('template1', () => { | |
let myDiv = document.getElementById(appDiv); | |
myDiv.innerHTML = ""; | |
const link1 = createLink('view1', 'Go to view1', '#/view1'); | |
const link2 = createLink('view2', 'Go to view2', '#/view2'); | |
myDiv.appendChild(link1); | |
return myDiv.appendChild(link2); | |
}); | |
template('template-view1', () => { | |
let myDiv = document.getElementById(appDiv); | |
myDiv.innerHTML = ""; | |
const link1 = createDiv('view1', "<div><h1>This is View 1 </h1><a href='#/'>Go Back to Index</a></div>"); | |
return myDiv.appendChild(link1); | |
}); | |
template('template-view2', () => { | |
let myDiv = document.getElementById(appDiv); | |
myDiv.innerHTML = ""; | |
const link2 = createDiv('view2', "<div><h1>This is View 2 </h1><a href='#/'>Go Back to Index</a></div>"); | |
return myDiv.appendChild(link2); | |
}); | |
// Define the mappings route->template. | |
route('/', 'template1'); | |
route('/view1', 'template-view1'); | |
route('/view2', 'template-view2'); | |
// For first load or when routes are changed in browser url box. | |
window.addEventListener('load', router); | |
window.addEventListener('hashchange', router); | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment