5

I just came across some odd behavior in Firefox 3.6/Mac. I suspect that it's general Firefox behavior, though.

I created two dead-simple test pages that change the window.location.href property to navigate to new URL:

If you try the following with either file:

  • Open a new/blank browser tab.
  • Paste the URL and hit "Enter".

You'll notice one difference between the two: using the first link, the browser's "Back" button is disabled; using the second, it's enabled and works as I'd expect it to.

The only difference between the two scripts is that the latter sets a one-second timeout before changing window.location.href.

I don't know why this happens, and I'm trying to achieve the behavior of the second script (where the "Back" button continues to work as expected) without causing any delay for the user.

My best guess is that maybe Firefox treats an immediate "redirect" by setting window.location.href the same as using the window.location.replace() method, since I think it's common for developers to use the former when they meant to use the latter. Maybe using setTimeout, since that causes the code to run asynchronously, defeats this behavior. Could that be the case?

I haven't experimented with the minimum value for setTimeout to achieve the desired effect, but I'll do that now. I would like to figure out why this happens exactly, though.

Thanks!

Bungle
  • 19,392
  • 24
  • 79
  • 106
  • The first works perfectly for me: hit the back button and come back to this page. For the second, one back shows a blank page, second back comes back here. If I open in a new tab, the first works as expected, no back available. The second goes back to a blank page. These are all the exact behaviors I would expect from your description. – Skip Head Sep 17 '10 at 00:32
  • 2
    @Skip Head - why? why would simply setting a timeout change the behavior? – sje397 Sep 17 '10 at 00:35
  • 1
    Tested some more browsers for you: Happens on Chrome on Linux/Mac and Opera for Mac. Doesn't happen on Safari for Mac or Firefox for Linux. – Robert Sep 17 '10 at 00:52
  • @Skip Head: As I understand it, the behavior of changing `window.location.href` should be to navigate to the specified URL, and then the "Back" button should take you back to the page that redirected you (thus redirecting you again). It sounds like you're seeing exactly the same behavior as I am, which is that using "Back" *skips* the redirect page, thus effectively working exactly like `window.location.replace()`, which is incorrect. – Bungle Sep 17 '10 at 00:58
  • Thanks, Robert! That's good to know - and suggests that this is a browser-specific (and apparently platform-specific) quirk of some kind. I'll do some more Googling to see if I can find any leads. – Bungle Sep 17 '10 at 01:04
  • Firefox, Chrome, and Opera on Windows all skip the redirect page on Back. IE8 loads the redirect page on Back, but then immediately redirects again. Safari on Windows loads the redirect page on Back, but just stays there. If the redirect is guaranteed to happen when the page loads, I think the skipping behaviour makes the most sense from a user perspective; otherwise (like in IE8) it would be impossible to go back past the redirect page by just clicking the single page back button. I have no idea what's up with Safari though, heh. – Tim Stone Sep 17 '10 at 01:24

2 Answers2

2

You are right in assuming that setting location.href while a page is loading is treated as a replace. There are in fact two separate behaviours.

The first is that setting location.href from script running as the result of parsing a tag is always interpreted as a replace. This was implemented to mirror Netscape 4 behaviour and subsequently tweaked.

The second is that any new document loaded as the result of an onload handler is also always interpreted as a replace. This was implemented and also tweaked.

But I'm curious as to why you are so keen to do this, as means that users would have to use the Back drop-down menu to go to the page before your page. (Going back one page would be no use if it kept on redirecting them to the current page.)

Neil
  • 54,642
  • 8
  • 60
  • 72
  • One reason why one wouldn't want to replace the current page in the history: I have a bookmarklet that assigns to window.location to jump from a page on one site (which I don't own) to a related page on another site. Without setTimeout, using the bookmarklet erases the starting page from the history. With setTimeout, it works the way one would expect: hit the bookmarklet, jump to the other page, then hit back to go back where you came from. – Dave Schweisguth May 13 '14 at 12:55
1

My best guess is that maybe Firefox treats an immediate "redirect" by setting window.location.href the same as using the window.location.replace() method, since I think it's common for developers to use the former when they meant to use the latter. Maybe using setTimeout, since that causes the code to run asynchronously, defeats this behavior. Could that be the case?

I've been told your guess is correct, but now that I look, there's doesn't appear to be any mention of this requirement in the HTML5 spec (linking to the most relevant page, since it's hard to link to the absence of requirement).

Nickolay
  • 31,095
  • 13
  • 107
  • 185