The simple app object defining routes and "life cycle" like functions.
Forked from Heydon's Pen Just add javascript.
| <nav role="navigation"> | |
| <ul> | |
| <li><a href="#the-default-view">the default view</a></li> | |
| <li><a href="#some-view">some view</a></li> | |
| <li><a href="#another-view">another view</a></li> | |
| </ul> | |
| </nav> | |
| <main role="main"> | |
| <div id="some-view"> | |
| <h1>Some view</h1> | |
| <p>This is one of any number of views that are reachable by linking to its <code>id</code> / hash identifier.</p> | |
| </div> | |
| <div id="another-view"> | |
| <h1>Another view</h1> | |
| <p>This is one of any number of views that are reachable by linking to its <code>id</code> / hash identifier.</p> | |
| </div> | |
| <div id="the-default-view"> | |
| <h1>The default view</h1> | |
| <p>This view is visible by default when the user first arrives at the app.</p> | |
| </div> | |
| </main> |
| (function() { | |
| var app = { | |
| // routes (ie. views and their functionality) defined here | |
| 'routes': { | |
| 'some-view': { | |
| 'rendered': function() { | |
| console.log('this view is "some-view"'); | |
| } | |
| }, | |
| 'another-view': { | |
| 'rendered': function() { | |
| console.log('this view is "another-view"'); | |
| app.routeElem.innerHTML = '<p>This javascript content overrides the static content for this view.</p>'; | |
| } | |
| } | |
| }, | |
| // The default view is recorded here. A more advanced implementation | |
| // might query the DOM to define it on the fly | |
| 'default': 'the-default-view', | |
| 'routeChange': function() { | |
| app.routeID = location.hash.slice(1); | |
| app.route = app.routes[app.routeID]; | |
| app.routeElem = document.getElementById(app.routeID); | |
| if (app.route) { | |
| app.route.rendered(); | |
| } | |
| }, | |
| // The function to start the app. | |
| 'init': function() { | |
| window.addEventListener('hashchange', function() { | |
| app.routeChange(); | |
| }); | |
| // If there's no hash in the URL, change the URL to | |
| // include the default view's hash | |
| if (!window.location.hash) { | |
| window.location.hash = app.default; | |
| } else { | |
| // Execute routeChange() for the first time | |
| app.routeChange(); | |
| } | |
| } | |
| }; | |
| window.app = app; | |
| })(); | |
| app.init(); |
| /* basic layout */ | |
| body { | |
| font-size: 120%; | |
| font-family: sans-serif; | |
| max-width: 40em; | |
| margin: 0 auto; | |
| } | |
| nav { | |
| text-align: center; | |
| padding: 0.5em 0; | |
| border-bottom: 2px solid; | |
| } | |
| nav li { | |
| display: inline-block; | |
| margin: 0 0.5em; | |
| } | |
| /* view visibility logic and animation */ | |
| main > * { | |
| display: none; | |
| } | |
| main > *:last-child { | |
| display: block; | |
| } | |
| @keyframes pulse { | |
| 0% { transform: scale(1) } | |
| 50% { transform: scale(1.05) } | |
| 100% { transform: scale(1) } | |
| } | |
| main > *:target { | |
| display: block; | |
| animation: pulse 0.5s linear 1; | |
| } | |
| main > *:target ~ * { | |
| display: none; | |
| } |