Inline Frames
You should use inline frames if you're concerned about browser compatibility. Some older browsers support IFRAME elements, but not the XmlHttpRequest object. There are also a few other reasons to use this approach:
-
The content being loaded into an IFRAME is displayed in the browser during the loading process, giving the end user a visual indication of progress.
-
Page caching always works with the content loaded into an IFRAME. Some versions of Opera are not very good at handling cached responses with the XmlHttpRequest object.
To implement this solution, insert an empty IFRAME into each DIV container and add a short JavaScript statement after each IFRAME, as follows:
<div id="header"> <div style="height: 100px; width: 100%"></div> <iframe id="header_iframe" style="height: 0px;"></iframe> <script>loadIframe("header","/navigation/header.html")</script> </div>
The id of the IFRAME should be equal to the id of the placeholder suffixed by _iframe. The loadIframe function takes two arguments: the id of the placeholder and the URL to load into it.
The loadIframe function that starts the load process is very simple:
function loadIframe(id,url) { try { var iframeObj = document.getElementById(id+"_iframe"); iframeObj.src = url ; } catch (err) { alert("cannot load "+url+" into "+id) ; } }
However, there's no mechanism to notify the requesting page that the desired content has been loaded into the placeholder IFRAME. The loaded content thus has to notify the parent page (via a JavaScript call) that it's ready to be used. The best moment to do this is after the page load has finished. The BODY tag in the IFRAME content should thus contain an onLoad event:
<body onload="contentLoaded('header')" style="margin: 0px 0px; padding: 0px 0px">
The contentLoaded function executed in the context of the IFRAME will extract the HTML content of the body and pass it to a function executing in the context of the parent page, which will use it to populate the placeholder:
-
contentLoaded, executed in the IFRAME context:
function contentLoaded(parentID) { var myContent = document.body.innerHTML ; parent.copyContent(parentID,myContent); }
-
copyContent, executed in the context of the parent web page:
function copyContent(id,content) { try { var placeholder = document.getElementById(id) ; placeholder.innerHTML = content; } catch (err) { alert("Cannot copy HTML content into "+id); } }
A careful reader should wonder by now about the reasons for this complexity—wouldn't it be simpler to load the navigational content in the IFRAME elements? As it turns out, there are a few caveats with that simplistic approach:
-
IFRAME has fixed height and width. If the content exceeds one or the other, it gets cropped or the IFRAME gets "decorated" with the scroll bars. HTML markup copied into a DIV element in the parent page is always perfectly sized.
-
When left within an IFRAME, the links (A elements) in the navigation content would load new pages within the IFRAME (unless you append target="_parent" to each link).
-
JavaScript event handlers attached to navigation elements would work within the context of IFRAME if left there. If you move the navigational content to the main page, the event handlers get access to functions and variables defined within the main page.