Skip to content

Instantly share code, notes, and snippets.

@plugnburn
Last active March 12, 2017 15:15
Show Gist options
  • Save plugnburn/67b2736ef7387de151b7 to your computer and use it in GitHub Desktop.
Save plugnburn/67b2736ef7387de151b7 to your computer and use it in GitHub Desktop.
R.js - parameterized client-side routing in 30 lines of JS

R.js

R.js is a 30-line JS library that brings life to the third part of minimalistic saga: parameterized client-side routing.

How to obtain

Download the library here or include the following into your HTML:

<script src="//cdn.rawgit.com/plugnburn/67b2736ef7387de151b7/raw/18135db0bd02eb610eb66962b8c8451f7732b5d3/r.min.js"></script>

Usage

Just two methods:

  • R(path, cb) - setup a route (you can use :param style - parameters object will be passed into the callback);
  • R.go(path) - resolve and go to a real existing path (relative to the root, for example, /articles/123/).

Examples

Setting up a route with id parameter: R('/view/:id/', function(params){console.log('Article ID:', params.id)})

Going to a previously defined route as if the user entered the URL: R.go('/view/5/')

That's it.

!function(w, routeCache, routing){
var routeCache = {}, callRoutePath = function(l){l = w.location; routing.go(l.pathname + l.search + l.hash, true)},
routing = function(path, cb, cacheObj) {
var cacheObj = {p: [], h: cb}, param,
regexString = path.replace(/\//g, '\\/'),
paramMatches = path.match(/:([^/]+)/ig)
if(paramMatches != null)
for(;param = paramMatches.shift();) {
cacheObj.p.push(param.slice(1))
regexString = regexString.replace(param, '([^/]+)')
}
cacheObj.r = RegExp(regexString, 'i')
routeCache[path] = cacheObj
}
routing.go = function(path, preventHistoryUpdates) {
var formalPath, matchList, cacheObj, params, i
for(formalPath in routeCache)
if(matchList = path.match((cacheObj = routeCache[formalPath]).r)) {
matchList.shift()
for(params = {}, i = cacheObj.p.length;i;)
params[cacheObj.p[--i]] = matchList.shift()
if(!preventHistoryUpdates) w.history.pushState({}, '', path)
return cacheObj.h(params)
}
}
w.R = routing
w.addEventListener('popstate', callRoutePath, false)
if(~['interactive','complete'].indexOf(document.readyState)) callRoutePath()
else w.addEventListener('DOMContentLoaded', callRoutePath, false)
}(this)
!function(g,h,c){h={};var k=function(a){a=g.location;c.go(a.pathname+a.search+a.hash,!0)};c=function(a,f,b){b={p:[],h:f};var d=a.replace(/\//g,"\\/"),e=a.match(/:([^/]+)/ig);if(null!=e)for(;f=e.shift();)b.p.push(f.slice(1)),d=d.replace(f,"([^/]+)");b.r=RegExp(d,"i");h[a]=b};c.go=function(a,f){var b,d,e,c;for(b in h)if(d=a.match((e=h[b]).r)){d.shift();b={};for(c=e.p.length;c;)b[e.p[--c]]=d.shift();f||g.history.pushState({},"",a);return e.h(b)}};g.R=c;g.addEventListener("popstate",k,!1);~["interactive","complete"].indexOf(document.readyState)?k():g.addEventListener("DOMContentLoaded",k,!1)}(this)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment