Back Button Support: Safari and Speed
via Ajaxian:
Daniel Kantor has implemented a Back button solution in Streampad and has shared it with us.
One of the main gripes against AJAX webapps is how they break the back button in a typical browser. There have been a few solutions (notably Brad Neuberg’s Really Simple History) but none have got it working in Safari. GMail still does not have a working back button in Safari.
They say the third time is the charm and I have tried to get a Back button thing in Streampad twice before. I do not want to use someone else’s library as they are usually more complex than I need and I did not want to put something in place until I had Safari working. I tried a few different techniques, but when I got it working in Safari, it would break in Firefox or IE.
I finally figured out a way to get this working in Firefox, IE and Safari.
While Daniel struggled with this, he found that the back button support caused a slow down in the entire app performance. He came up with a new solution that didn't suffer from the performance issues:
The general concept is this: You load a page into an iframe that calls parent.goBack() and then changes its own location to a new page (a blank page will do). Because the page jumps to a new location, it now has a history. If you click the back button, it will load the page again (calling parent.goBack()) and then spring forward to the dummy blank page.
JavaScript:
var historyArray = Array(); // create an empty array to hold the history
var historyCounter = -1; // initialize the array pointer to -1function historyAdd(f){
if (historyCounter == -1){ // the first time this is called it will change the iframe location
document.getElementById(’hFrame’).src = “/historySpring.php”;
}var o = historyArray[historyCounter];
if (f != o){ // don’t put in consecutive duplicates
historyCounter++
historyArray[historyCounter] = f; // add function to history
}function goBack() {
if (historyCounter> 0){ // don’t want to call it if there is nothing in history array
historyCounter– // set the pointer back one
var f = historyArray[historyCounter]; // get the function from the history array
f = f+”()”;
eval(f); // call the function
}
}

Leave a Reply