Backbone History Replace Refresh

some are seeing unexpected page reloads when using Backbone.history.navigate with replace=true

by Nick Iaconis

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone.js"></script>

JavaScript

app = {}

function navigateToLink( event ) {
    var $target = $(event.target);
    app.router.navigate( $target.attr('data-link-target'), {
        trigger: true,
        replace: $target.attr('data-link-replace')
    } );
}

function goBack() {
        window.history.back();
}

app.BaseView = Backbone.View.extend({
    events: {
        'click a.link': navigateToLink,
        'click a.back': goBack
    },
    initialize: function() {
        this.render();
    }
});

app.viewA = new (app.BaseView.extend({
    render: function() {
        this.$el.html(
            '<div>This is view A.</div>\n<a href="javascript:void(0)" class="link" data-link-target="viewB">Click here to go to view B.</a>'
            );
    }
}));

app.viewB = new (app.BaseView.extend({
    render: function() {
        this.$el.html(
            '<div>This is view B.</div>\n<a href="javascript:void(0)" class="link" data-link-target="viewC" data-link-replace="true">Click here to replace view B with view C.</a>\n<br>\n<a href="javascript:void(0)" class="back">Click here to trigger history.back()</a>'
            );
    }
}));

app.viewC = new (app.BaseView.extend({
    render: function() {
        this.$el.html(
            '<div>This is view C.</div>\n<a href="javascript:void(0)" class="back">Click here to trigger history.back()</a>'
            );
    }
}));

app.router = new (Backbone.Router.extend({
    routes: {
        '': 'entryPoint',
        'viewA': 'routeViewA',
        'viewB': 'routeViewB',
        'viewC': 'routeViewC'
    },
    entryPoint: function() {
        this.navigate( 'viewA', true );
    },
    routeViewA: function routeViewA() {
        $('body>*').detach();
        $('body').append( app.viewA.$el );
    },
    routeViewB: function routeViewB() {
        $('body>*').detach();
        $('body').append( app.viewB.$el );
    },
    routeViewC: function routeViewC() {
        $('body>*').detach();
        $('body').append( app.viewC.$el );
    }
}));

Backbone.history.start();