-
-
Save philoye/2841035 to your computer and use it in GitHub Desktop.
A Backbone.js router subclass that disables the hash fallback mechanism in favour of just navigating to the location (just like a normal link would behave)
This file contains hidden or 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
class MyApp.Router extends Backbone.Router | |
hasPushState: window.history and window.history.pushState | |
# Override the navigate function to remove Backbone's #hash fallback for | |
# non-pushState browsers. Instead we just navigate to the new location using | |
# window.location | |
navigate: (fragment, trigger) -> | |
if @hasPushState | |
super(arguments...) | |
else | |
# Backbone navigate paths don't start with a forward slash, so we may | |
# need to add one | |
fragment = "/#{fragment}" unless fragment.match(/^\//) | |
window.location = fragment | |
# Navigates to the href property of an event's currentTarget whilst ignoring | |
# right clicks, middle clicks, shift-clicks etc. | |
# | |
# Handy for using from within event handlers: | |
# | |
# class MyApp.HeaderView extends Backbone.View | |
# events: | |
# "click a.home": "home" | |
# home: (e) -> | |
# MyApp.router.navigateToLink(e) | |
navigateToLink: (e, trigger=true) -> | |
if e.which == 2 or e.metaKey or e.ctrlKey or e.shiftKey | |
# Make sure we return true in case we're used as the return value for | |
# the event handling function | |
return true | |
else | |
# Update document page title if title attribute is set on the link | |
document.title = 'MyAppName' | |
if e.target.title | |
document.title = e.target.title + ' - ' + document.title | |
# Backbone navigate paths don't start with a forward slash | |
@navigate e.target.pathname.replace(/^\//,''), trigger | |
e.preventDefault() | |
# Send all links to the Router if data-app="true" is set. | |
# | |
# This way you don't have to explicitly set up events for routing. You can | |
# simply user normal links and backbone transparently takes over. | |
# | |
# <a href="/home" data-app="true" title="Homepage">Home</a> | |
initialize: -> | |
$(document).on "click", 'a', (e) => | |
if $(e.target).attr('data-app') | |
e.preventDefault() | |
@navigateToLink e | |
# your backbone init stuff | |
This file contains hidden or 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
(function() { | |
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { | |
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } | |
function ctor() { this.constructor = child; } | |
ctor.prototype = parent.prototype; | |
child.prototype = new ctor; | |
child.__super__ = parent.prototype; | |
return child; | |
}, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; | |
MyApp.Router = (function() { | |
__extends(Router, Backbone.Router); | |
function Router() { | |
Router.__super__.constructor.apply(this, arguments); | |
} | |
Router.prototype.hasPushState = window.history && window.history.pushState; | |
Router.prototype.navigate = function(fragment, trigger) { | |
if (this.hasPushState) { | |
return Router.__super__.navigate.apply(this, arguments); | |
} else { | |
if (!fragment.match(/^\//)) { | |
fragment = "/" + fragment; | |
} | |
return window.location = fragment; | |
} | |
}; | |
Router.prototype.navigateToLink = function(e, trigger) { | |
if (trigger == null) { | |
trigger = true; | |
} | |
if (e.which === 2 || e.metaKey || e.ctrlKey || e.shiftKey) { | |
return true; | |
} else { | |
document.title = 'MyAppName'; | |
if (e.target.title) { | |
document.title = e.target.title + ' - ' + document.title; | |
} | |
this.navigate(e.target.pathname.replace(/^\//, ''), trigger); | |
return e.preventDefault(); | |
} | |
}; | |
Router.prototype.initialize = function() { | |
return $(document).on("click", 'a', __bind(function(e) { | |
if ($(e.target).attr('data-app')) { | |
e.preventDefault(); | |
return this.navigateToLink(e); | |
} | |
}, this)); | |
}; | |
return Router; | |
})(); | |
}).call(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment