Skip to content

Instantly share code, notes, and snippets.

@aurri
Last active August 29, 2015 14:03
Show Gist options
  • Save aurri/4e48c2b0f8c36a8c2706 to your computer and use it in GitHub Desktop.
Save aurri/4e48c2b0f8c36a8c2706 to your computer and use it in GitHub Desktop.
Simple minimal router
/////////////////////////////////////////////////
//// 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
}
}
@tipiirai
Copy link

tipiirai commented Jul 6, 2014

Very cool and minimal! I like this.

Why the IE9 limitation? Because of the map function?
Please educate me: why use DOMContentLoaded instead of onpopstate?

@aurri
Copy link
Author

aurri commented Jul 7, 2014

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