|
@@ -0,0 +1,121 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<!--
|
|
|
+ Joakim Beng's simple client-side routing example, with John Resig's simple router
|
|
|
+
|
|
|
+ @see http://joakim.beng.se/blog/posts/a-javascript-router-in-20-lines.html
|
|
|
+
|
|
|
+ @see http://ejohn.org/blog/javascript-micro-templating/
|
|
|
+-->
|
|
|
+<html>
|
|
|
+ <head>
|
|
|
+ <meta charset="utf-8">
|
|
|
+ <title>Building a router</title>
|
|
|
+ <script type="text/ecmascript">
|
|
|
+ // Simple JavaScript Templating
|
|
|
+ // John Resig - http://ejohn.org/ - MIT Licensed
|
|
|
+ (function () {
|
|
|
+ var cache = {};
|
|
|
+
|
|
|
+ this.tmpl = function tmpl(str, data) {
|
|
|
+ // Figure out if we're getting a template, or if we need to
|
|
|
+ // load the template - and be sure to cache the result.
|
|
|
+ var fn = !/\W/.test(str) ?
|
|
|
+ cache[str] = cache[str] ||
|
|
|
+ tmpl(document.getElementById(str).innerHTML) :
|
|
|
+
|
|
|
+ // Generate a reusable function that will serve as a template
|
|
|
+ // generator (and which will be cached).
|
|
|
+ new Function("obj",
|
|
|
+ "var p=[],print=function(){p.push.apply(p,arguments);};" +
|
|
|
+
|
|
|
+ // Introduce the data as local variables using with(){}
|
|
|
+ "with(obj){p.push('" +
|
|
|
+
|
|
|
+ // Convert the template into pure JavaScript
|
|
|
+ str
|
|
|
+ .replace(/[\r\t\n]/g, " ")
|
|
|
+ .split("<%").join("\t")
|
|
|
+ .replace(/((^|%>)[^\t]*)'/g, "$1\r")
|
|
|
+ .replace(/\t=(.*?)%>/g, "',$1,'")
|
|
|
+ .split("\t").join("');")
|
|
|
+ .split("%>").join("p.push('")
|
|
|
+ .split("\r").join("\\'")
|
|
|
+ + "');}return p.join('');");
|
|
|
+
|
|
|
+ // Provide some basic currying to the user
|
|
|
+ return data ? fn(data) : fn;
|
|
|
+ };
|
|
|
+ })();
|
|
|
+ </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>
|
|
|
+
|
|
|
+ <script type="text/ecmascript" id="routing">
|
|
|
+ // A hash to store our routes:
|
|
|
+ var routes = {};
|
|
|
+ // The route registering function:
|
|
|
+ function route(path, templateId, controller) {
|
|
|
+ routes[path] = {
|
|
|
+ templateId: templateId,
|
|
|
+ controller: controller
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ // Now declare the routes.
|
|
|
+ route('/', 'home', function () {
|
|
|
+ });
|
|
|
+
|
|
|
+ route('/page1', 'template1', function () {
|
|
|
+ this.greeting = 'Hello world!';
|
|
|
+ this.moreText = 'Bacon ipsum...';
|
|
|
+ });
|
|
|
+
|
|
|
+ route('/page2', 'template2', function () {
|
|
|
+ this.heading = 'I\'m page two!';
|
|
|
+ });
|
|
|
+
|
|
|
+ // The router.
|
|
|
+ var el = null;
|
|
|
+ function router () {
|
|
|
+ // Lazy load view element:
|
|
|
+ el = el || document.getElementById('view');
|
|
|
+ // Current route url (getting rid of '#' in hash as well):
|
|
|
+ var url = location.hash.slice(1) || '/';
|
|
|
+ // Get route by url:
|
|
|
+ var route = routes[url];
|
|
|
+ // Do we have both a view and a route?
|
|
|
+ if (el && route && route.controller) {
|
|
|
+ // Render route template with John Resig's template engine:
|
|
|
+ el.innerHTML = tmpl(route.templateId, new route.controller());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Listen on hash change:
|
|
|
+ window.addEventListener('hashchange', router);
|
|
|
+ // Listen on page load:
|
|
|
+ window.addEventListener('load', router);
|
|
|
+ </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>
|
|
|
+ </body>
|
|
|
+</html>
|