Clean Up Events With Backbone Routers

How to trigger cleanup events for a given route when that route is no longer active

by Adam Boduch

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<ul>
    <li><a href="#page1">Page 1</a></li>
    <li><a href="#page2">Page 2</a></li>
</ul>

JavaScript

// Variables. Less typing later on.
var Router = Backbone.Router,
    proto = Router.prototype,
    app;

// Define and instantiate a new Backbone router.
app = new ( Router.extend({
    
    // Some simple routes for our app.
    routes: {
        'page1': 'page1',
        'page2': 'page2',
        '*path': 'default'
    },
    
    // Override the trigger method to provide
    // custom cleanup behavior.
    trigger: function() {
        
        // Get the trigger args and check if this is a
        // "route" event.
        var args = Array.prototype.slice.call(
                arguments ),
            result = ( /^route:(\w*)$/ ).exec( args[ 0 ] );
        
        // If this is a route event, cleanup any previous
        // routes and update the "prevArgs" array.
        if ( result ) {
            this.cleanup();
            this.prevArgs = [ 'cleanup:' + result[ 1 ] ]
                .concat( args.slice( 1 ) );
        }
        
        // Trigger the original event.
        return proto.trigger.apply( this, args );
    
    },
    
    // Triggers a special "cleanup:routeName" event
    // if prevArgs is an array.
    cleanup: function() {
        if ( this.prevArgs ) {
            proto.trigger.apply( this, this.prevArgs );
        }
    }
    
}))();

// Respond to "page1".
app.on( 'route:page1', function() {
    $( 'a[href="#page1"]' )
        .css( 'font-weight', 'bold' );
});

// Cleanup "page1" when the route changes.
app.on( 'cleanup:page1', function() {
    $( 'a[href="#page1"]' )
        .css( 'font-weight', 'normal' );
});

// Respond to "page2".
app.on( 'route:page2', function() {
    $( 'a[href="#page2"]' )
        .css( 'font-weight', 'bold' );
});

// Cleanup "page2" when the route changes.
app.on( 'cleanup:page2', function() {
    $( 'a[href="#page2"]' )
        .css( 'font-weight', 'normal' );
});

$(function() {
    Backbone.history.start();    
});