Last active
August 29, 2015 14:03
-
-
Save aurri/4e48c2b0f8c36a8c2706 to your computer and use it in GitHub Desktop.
Simple minimal router
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
///////////////////////////////////////////////// | |
//// Simple minimal router (works in IE9+) | |
///////////////////////////////////////////////// | |
/*** Usage ************************************** | |
//// Navigate to url | |
route('/path') | |
//// Replace url (w/o history entry) | |
route('/path', true) | |
//// Listen for every url change | |
route(function(params...){}) | |
//// Map routes to specific handlers | |
var routes = route() // Or: route(routes) | |
// Handle "/" | |
routes.home = function(){ alert('welcome home') } | |
// Handle "/hello/*" | |
routes.hello = function(size, thing){ | |
// If no "thing" param (/hello/size), redirect to default thing (skipping history entry) | |
if(!thing) return route('/hello/big/'+thing, true) | |
// If no "size" param (/hello), cancel the route (redirects home) | |
if(!size) return false | |
// If everything's ok, do the thing | |
alert('greetings from the '+size+' '+thing) | |
} | |
************************************************/ | |
function route(){ | |
var methods = {'string':navigate, 'function':listen, 'object':map, 'undefined':map} | |
methods[typeof arguments[0]].apply(null, arguments) | |
function navigate(path, replace){ | |
replace | |
? location.replace('#'+path) | |
: location.hash = '#'+path | |
} | |
function listen(cb){ | |
document.addEventListener('DOMContentLoaded', onChange) | |
window.addEventListener('hashchange', onChange) | |
function onChange(){ cb.apply(null, location.hash.split('/').slice(1)) } | |
} | |
function map(handlers){ | |
handlers = handlers || {} | |
listen(function(){ | |
var args = Array.prototype.slice.call(arguments) | |
var handler = handlers[args.shift() || 'home'] | |
handler && handler.apply(handlers, args) === false && navigate('/', true) | |
}) | |
return handlers | |
} | |
} |
The IE9 limitation comes from DOMContentLoaded
, which is supported only in IE9+.
DOMContentLoaded
handles the initial url. I did't use popstate, because it requires IE10. Also it seems that popstate
doesn't reliably fire on page load across browsers (namely Firefox), hence the need for DOMContentLoaded
.
Even though this mapping of routes to methods looked nice at first sight, it eventually ended up being too restrictive for me. I also missed a way for silently manipulating a url without trigerring the event handlers (which sadly requires popstate
, which means IE10+), as well as a simpler API for all the different ways of changing the url. So it all came down to just this: https://gist.github.com/aurri/faf17a9f5c1f7d3ede2d
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Very cool and minimal! I like this.
Why the IE9 limitation? Because of the
map
function?Please educate me: why use
DOMContentLoaded
instead ofonpopstate
?