Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js PushStates: Fallback for Internet Explorer not working

My site has just implemented pushstates in Backbone.js and the entire site breaks for IE. How should I create a fallback for IE?

What I am trying to achieve

Main URL: http://mydomain.com/explore

Another URL: 'http://mydomain.com/explore/1234

The main page of the site is http://mydomain.com/explore which triggers the router function explore.

When a user visits http://mydomain.com/explore/1234, Backbone's router will trigger the function viewListing, which is the same as function explore, but also includes details for item id 1234.

Backbone.js Router

// Router
var AppRouter = Backbone.Router.extend({
    routes: {
        'explore': 'explore',
        'explore/:id': 'viewListing',
    },

    explore: function() {
        this.listingList    = new ListingCollection();
        // More code here
    },

    viewListing: function(listing_id) {
        this.featuredListingId = listing_id;    // Sent along with fetch() in this.explore()
        this.explore();
    }
});

App = new AppRouter();

// Enable pushState for compatible browsers
var enablePushState = true;  

// Disable for older browsers (IE8, IE9 etc)
var pushState = !!(enablePushState && window.history && window.history.pushState);

if(pushState) {
    Backbone.history.start({
        pushState: true,
        root: '/'
    })
} else {
    Backbone.history.start({
        pushState: false,
        root: '/'
    })
}

Problem: As you can see in the above code, I tried to disable pushstates with pushState: false if it is an incompatible browser.

However for IE to access what would normally work for a normal browser (http://mydomain.com/explore), IE will need to go to http://mydomain.com/explore/#explore which is making things confusing! Further more to access http://mydomain.com/explore/1234 IE needs to go to http://mydomain.com/explore/#explore/1234

How should this be fixed?

like image 646
Nyxynyx Avatar asked Nov 06 '12 15:11

Nyxynyx


1 Answers

If you don't want http://mydomain.com/explore/#explore url, then you have to redirect to http://mydomain.com/#explore so Backbone will start with it instead.

if(!pushState && window.location.pathname != "/") {
  window.location.replace("/#" + window.location.pathname)
}

UPD: you'll probably have to remove the leading slash when setting path as a hash window.location.pathname.substr(1)

UPD2: if you want /explore/ to be the root for your backbone routes then you have to exclude it from routes and set as a root in History.start({root: "/explore/"})

routes: {
    '': 'explore',
    ':id': 'viewListing',
}
like image 167
Andrey Kuzmin Avatar answered Sep 28 '22 15:09

Andrey Kuzmin