-
-
Save DKunin/8000668 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Building a router</title> | |
<script> | |
// Put John's template engine code here... | |
(function () { | |
// A hash to store our routes: | |
var routes = {}; | |
// The route registering function: | |
function route (path, templateId, controller) { | |
// Allow route(path, controller) for template less routes: | |
if (typeof templateId === 'function') { | |
controller = templateId; | |
templateId = null; | |
} | |
routes[path] = {templateId: templateId, controller: controller}; | |
} | |
var el = null, current = null; | |
function router () { | |
// Current route url (getting rid of '#' in hash as well): | |
var url = location.hash.slice(1) || '/'; | |
// Get route by url: | |
var route = routes[url]; | |
// Is it a route without template? | |
if (route && !route.templateId) { | |
// Just initiate controller: | |
return route.controller ? new route.controller : null; | |
} | |
// Lazy load view element: | |
el = el || document.getElementById('view'); | |
// Clear existing observer: | |
if (current) { | |
Object.unobserve(current.controller, current.render); | |
current = null; | |
} | |
// Do we have both a view and a route? | |
if (el && route && route.controller) { | |
// Set current route information: | |
current = { | |
controller: new route.controller, | |
template: tmpl(route.templateId), | |
render: function () { | |
// Render route template with John Resig's template engine: | |
el.innerHTML = this.template(this.controller); | |
} | |
}; | |
// Render directly: | |
current.render(); | |
// And observe for changes: | |
Object.observe(current.controller, current.render.bind(current)); | |
} | |
} | |
// Listen on hash change: | |
this.addEventListener('hashchange', router); | |
// Listen on page load: | |
this.addEventListener('load', router); | |
// Expose the route register function: | |
this.route = route; | |
})(); | |
</script> | |
<script type="text/html" id="home"> | |
<h1>Router FTW!</h1> | |
</script> | |
<script type="text/html" id="template1"> | |
<h1>Page 1: <%= greeting %></h1> | |
<p><%= moreText %></p> | |
</script> | |
<script type="text/html" id="template2"> | |
<h1>Page 2: <%= heading %></h1> | |
<p>Lorem ipsum...</p> | |
</script> | |
</head> | |
<body> | |
<ul> | |
<li><a href="#">Home</a></li> | |
<li><a href="#/page1">Page 1</a></li> | |
<li><a href="#/page2">Page 2</a></li> | |
</ul> | |
<div id="view"></div> | |
<script> | |
route('/', 'home', function () {}); | |
route('/page1', 'template1', function () { | |
this.greeting = 'Hello world!'; | |
this.moreText = 'Loading...'; | |
// Simulating an Ajax call which take 0.5 s | |
setTimeout(function () { | |
this.moreText = 'Bacon ipsum...'; | |
}.bind(this), 500); | |
}); | |
route('/page2', 'template2', function () { | |
this.heading = 'I\'m page two!'; | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment