views:

80

answers:

2

For the purpose of the question I need to create a simple fictitious scenario.

I have the following trivial page with one link, call it page A:

<a class="red-anchor" onclick="change_color(event);" href="http://mysite.com/b/"&gt;B&lt;/a&gt;

With the associated Javascript function:

function change_color(e)
{
  var event = e || window.event;
  var link = event.target;
  link.className = "green-anchor";
}

And I have the appropriate CSS to make the anchor red or green based on the classname.

This is working. That is, when I click the anchor it changes color from red to green, which is briefly visible before the browser loads page B.

But if I then use the BACK button to return to page A I get different behavior in different browsers.

  • In Safari, the anchor is still green (desired behavior)
  • In Firefox it reverts to red

I imagine that Safari is somehow updating its cached version of the page, whereas Firefox isn't.

So my first question is: is there any way to get FF to update the cached page, or is something else happening here?

Secondly: I have a different implementation where I use an ajax call. In this I set the class of the anchor using a session variable, something like...

<a class="<?php echo $_SESSION["color"]; ?>"  ...[snip]... >B</a>

And the javascript function makes an additional ajax call that changes the "color" session variable.

In this case both Safari and Firefox work as expected. When going back from B to A the color is still green. But I can't for the life of me figure out why it should be different to the non-ajax case. I have tried many different permutations and for it to work on FF the "color" session variable MUST change (i.e. the ajax call itself is not somehow reloading the cache). But on coming BACK, the page is being reloaded from the cache (verified in Firebug), so how is the page even accessing this session variable if it isn't reprocessing the page and running that fragment of php in the anchor?

I figure there must be something fundamental here that I am not understanding. Any insight would be much appreciated.

+1  A: 

In Firefox it reverts to red

It doesn't revert to red so much as it remains red. It's not a new page when you go ‘back’ to it, it's the exact same page object: it was only hidden when you navigated away from it, not immediately discarded; when you return the old DOM gets pulled back onto the screen together with all the changed you made to it and all the script content running in it continues to operate.

This feature is called the bfcache and both Firefox and Safari have it (as well as Opera). I don't know why it's not kicking in for you in Safari... maybe there are some different caching settings in the browsers, you you cleared the page from cache by navigating or waiting longer, or something.

is there any way to get FF to update the cached page

Well you can break the bfcache by setting any event handler on onunload (even a do-nothing function() {}), but it's not ideal. You'll make navigation around your pages needlessly slower. What is the purpose of the colour change, what's it supposed to indicate that needs to be reset when you go back?

What should happen if you click the link and then hit Escape to cancel the navigation? How about setting the colour back on a setTimeout call, navigation or not?

bobince
The purpose is a read/unread indicator. The fact that page B is read is stored to the DB, but since the back button reloads the page from the cache (or re-uses the DOM, as you put it) this isn't updated. I was hoping to achieve this using the javascript above.Just to make sure I was clear... I changed the DOM to green using the javascript, but when I return that change isn't reflected in FF. That is what I mean by FF reverts to red.Safari behaves as you say - the DOM is unchanged when I come back from page B.
Greg
Thanks bobince - this put me on the right track.
Greg
Ah, OK, so you *want* the bfcache behaviour! The only way I can think of to make the ‘read’ness persist without reloading the page would be to start storing cookies (or other client-side storage mechanism) or AJAX back to the server to get an update. Maybe simply relying on `:visited` styling would be easier?
bobince
A: 

To answer my own question, this was a caching issue. Safari wasn't caching the page, which made it appear to me that my Javascript changes to the DOM had persisted through navigating away and returning using the BACK button.

To summarize:

  1. No post-page-load Javascript changes to the DOM survive on either browser because the cached version is the one originally loaded with the page
  2. FF and Safari were behaving differently because FF needs "no-store" in the Cache-Control header directive - "no-cache" is not sufficient to disable caching for the page

More on #2 can be found here: http://blog.httpwatch.com/2008/10/15/two-important-differences-between-firefox-and-ie-caching/

Greg