olivernn / davis.js

RESTful degradable JavaScript routing using pushState
http://davisjs.com
532 stars 58 forks source link

Chrome fires on initial popstate event #52

Closed stoplion closed 12 years ago

stoplion commented 12 years ago

Chrome fires on initial popstate event, causing the page to render twice.

olivernn commented 12 years ago

Thanks for letting me know. To make it easier to debug this please could you put together a simple test case that shows the problem, as well as letting me know what version of Davis and Chrome you are seeing the issue in. Having this will make resolving this problem much easier and quicker.

adrazich commented 12 years ago

I am having the same issue. I posted this on stackoverflow a week ago. (http://stackoverflow.com/questions/12062274/davis-js-generating-two-requests-on-page-load-reload).

When I reload or load a page in chrome(21.0.1180.82) /safari (6.0 (8536.25)) it will generate two requests to my route. When I click on a link it only generates one request. In firefox loading, reloading and clicking on a link will generate only one request. I only want one request to fire so I don't redraw my content and do my animations twice.

Is there a way I can fix this so I only ever get one request? Should I put a timeout on my route so it can only send one request per x milliseconds? That sounds like a hack though.

Explanation of what I'm doing: I have a single index page which uses the route to load different content in. It grabs the data from an API and loads an underscore template then places it in the content container.

I am using the latest version of davis.js 0.9.2.

I also just noticed that if I only have 1 route it works fine; it's only when I have multiple routes.

Here's my setup:

var app = Davis(function(){
    this.configure(function(){
      this.generateRequestOnPageLoad = true;
    });

    this.get(directory, function(){
      RenderPage('index');
    });

    this.get(directory+':id', function(req){
      RenderPage(req.params['id']);
    });

    this.get(directory+':id/:page', function(req){
      RenderPage(req.params['id'], req.params['page']);
    });
});

And here's what my console is outputting:

Firefox

[Tue Aug 21 2012 16:02:01 GMT-0400 (EDT)] application started
[Tue Aug 21 2012 16:02:01 GMT-0400 (EDT)] runRoute: GET /catalog/users

Chrome

[Tue Aug 21 2012 16:01:59 GMT-0400 (EDT)] application started
[Tue Aug 21 2012 16:01:59 GMT-0400 (EDT)] runRoute: GET /catalog/users
[Tue Aug 21 2012 16:01:59 GMT-0400 (EDT)] runRoute: GET /catalog/users 
olivernn commented 12 years ago

Thanks for these details, I hadn't seen this question on StackOverflow but this is probably enough to go on to work out a fix.

Using a timeout is probably not the way to go, this is definitly a bug in Davis.

It is weird that the issue doesn't happen when there is only one route.

olivernn commented 12 years ago

I've pushed a new version of davis (0.9.3) that should fix this issue. Let me know if you continue to have these issues.