This is my personal blog. The views expressed on these pages are mine alone and not those of my employer.

Wednesday, August 24, 2005

AJAX Tutorial: A Tale of Two IFrames (or, How To Control Your Browsers History)

This is a mini-tutorial on the black art of iframes and browser history, known to AJAX experts but rarely presented clearly.

An iframe is an internal frame that can point to and load up an arbitrary URL within your HTML page. Here is an example small iframe showing Google, right in this document:



Your browser history is the list of pages you have visited. When you press the back and forward buttons in your browser, you are jumping through your browser history.

Sometimes, for various reasons, programmers want to control what is placed into their browser's history or not. Think of this as a primitive that can be used in more elaborate AJAX and DHTML hacks; it's a building block useful in all kinds of crazy AJAX kung-fu. It's good to know about these tricks when confronted with AJAX design issues, or when you stumble across very strange bugs which might be caused by the different kinds of iframes I will present.

There are two kinds of iframes, those that are right within your HTML and loaded in the page:
<html>
<body>
<iframe id="testFrame"
src="http://www.google.com">
</iframe>
</body>
</html>
and those that are created dynamically, through the DOM and JavaScript, after the page is finished loading:
<html>
<head>
<script language="JavaScript">
function initialize() {
var testFrame =
document.createElement("IFRAME");
testFrame.id = "testFrame";
testFrame.src = "http://www.google.com";
document.body.appendChild(testFrame);
}
</script>
</head>

<body onload="initialize()">
</body>
</html>

Okay, fine, so there are two kinds of iframes; who cares? Well, it turns out these two kinds of iframes have completely different behaviors when it comes to history in different browsers!

Here's the lowdown for each kind of browser.

In Firefox:
In Internet Explorer:
In Safari:
You can see this for yourself with the following demos. In both demos we dynamically change the iframe's location between four different web sites.

In the first demo, when we are dealing with an iframe that is in the HTML on page load, you will find that all of these sites are in the browser's history in both Firefox and IE. Press the back and forward buttons when the popup saying "Finished" appears, and you will see the iframe's contents change between each site.

In the second demo, when we are dealing with a dynamicly created iframe, you will find that only the initial page load is in the browser's history, while all sites are in the history in IE.

One small footnote. If you have a static iframe that is loaded in the HTML, and that iframe has a src value initially:

<iframe src="http://www.google.com"></iframe>


then this initial value is not placed into the browser's history, only successive changes to that static iframe are placed into the history.

You can use the special behavior of these two kinds of iframes for some real trickery. I won't go too much into possible uses, since I mostly want to highlight the differences between these two iframes in this tutorial. First, you make them invisible using CSS. Then, you decide whether you want something to enter the history or not, choosing the appropriate kind of iframe. If you are using the iframe remote communication technique instead of XmlHttpRequest, for old browser compatibility, knowing the difference between these two kinds of iframes can be very useful, since you can choose whether remote iframe communication is placed into the history or not.

Comments:
In your second demo, try running the "initialize" method called from the onload on a timer:

< body onload="setTimeout('initialize()', 100);" >

This will cause FF to add all the sites to the browser history.

Next you can try commenting out everything except for the few lines of code that dynamically create and append the IFRAME. Notice that an entry is still added to the stack on FF.

Fun stuff. Basically, FF allows you to manipulate and dynamically create IFrames all you want during the loading sequence. Once loading is complete (after onload() fires), any dynamically created iframes or src changes are recorded in the browser history. I haven't been able to work around this bug in FF.
 
Running FF1.5 here seems to have the same behaviour as you describe IE having, haven't gone *back* and tried it in 1.0 yet to see the difference :-)
 
In Safari Version 2.0.3 (417.8) It seems like browser history works in the sense that an iframe that exists in the document, does keep history. It does appear to cause safari to do a complete page reload rather then just the iframe. So, functionally it's equivalent - just not so efficent
 
How do i then come to know if an iFrame has loaded or it might have returned a 404 or 500 error so that I can tell my visitors that site failed to load. I can do this while using XMLHTTPRequest... but what about iFrames? please tell me at rohan2kool@gmail.com
 
I want to achieve the history effect like here with static iframe. In detail, when you enter some queries each query becomes part of the history.

Then when you leave the site and click back the last query is back again. Works for me in both IE and FF.

But how do you get this behaviour, cannot get it running on my site, only with FF - IE loads always first stae of irame.

What is the hidden magic?
 
In you first demo, after you go through till the fourth page and then do a load of new page(like a google.com link), would the history that was working earlier still work. Because I have a problem with such a case. All I want is that the history works even after a page is loaded.If you could please suggest me a solution it would be great and to make it simple, all I am is looking for is something that works in just IE(need not really make the solution cross browser).Thanks, Ranjith.
 
Hi Ranjith, that should work; it's one of RSH's unique selling points that history is conserved even if you type a different domain then come back. Is that not working for you? If it isn't send me details on your platform so I can have a bug report.
 
As "noiv" was asking "whats the hidden magic", because thats where
my IE fails too. I want to let you know that I am not using RSH(made a mistake by not visiting this blog earlier, otherwise would have learnt and used RSH). I also cant switch to RSH now. Making it abstract, i have page which goes through states 1 through 4 upon each edit. Once i click back on state 4 it works and goes to 3 and so on. But assume that there is a hyperlink on state 4 which is a new page load. Once the back button is clicked IE goes to the history with state 1 instead of the state 4 history. What am i missing here in my implementation. Thanks, Ranjith
 
Would the problem be simplified by querying the history objects length parameter?

Before the request happens, save the history length and query it afterwards. I think with this concept, there should be a workable solution
 
Would the problem be simplified by querying the history objects length parameter?

Before the request happens, save the history length and query it afterwards. I think with this concept, there should be a workable solution
 
Nice read. How about a third kind of iframe? one that is created using innerHTML instead of createElement()? Or is that approach (innerHTML) looked down upon...?
 
What I meant was; with the innerHTML approach, neither IE nor FF (nor Netscape nor Opera) store any kind of history ... I haven't tried using RSH for this scenario yet ... has anyone done something (dumb?) like this?
 
why do the comments have time stamp but no date stamp? in any event I'm guessing this info might be outdated as of 6/3/2008.
 
I am having same issue as described by Ranjith Arvapalli i.e. coming back to step4 after going off-site in IE. Please see this post http://preview.tinyurl.com/cwpejv. Let me know if anyone found solution
 
Issue was resolved after removing Google map code. We are still wondering what is the real issue and how to resolve it.
 
Am I able to modify the CSS used in an iframe? ie take a form from my site A and rebrand it for site B while still keeping all my data signups and page tracking in one place?
 
Has anyone been able to fix the bug in FF where it adds the original page to the history if you change the iframe "src" after the onload event?
 
Post a Comment



Links to this post:

Create a Link



<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]