Advanced Search

View RSS Feed

molendijk

Deferred document.write

Rate this Entry
While surfing on the Internet I found this page on how to pass data from one page to another. After a while, I realized that the script used on the page actually contains a technique (implicitly) for deferring document.write. Just for the fun of it, I modified the script so as to have some easy ways of dynamically inserting internal and external content into a given div via document.write. Here it is:
Code:
<script type="text/javascript">
function HttpRequest(url){
var pageRequest = false //variable to hold ajax object
/*@cc_on
@if (@_jscript_version >= 5)
try {
pageRequest = new ActiveXObject("Msxml2.XMLHTTP")
}
catch (e){
try {
pageRequest = new ActiveXObject("Microsoft.XMLHTTP")
}
catch (e2){
pageRequest = false
}
}
@end
@*/

if (!pageRequest && typeof XMLHttpRequest != 'undefined')
pageRequest = new XMLHttpRequest()

if (pageRequest){ //if pageRequest is not false
pageRequest.open('GET', url, false) //get page synchronously
pageRequest.send(null)

external_data=pageRequest.responseText
}
}

document.write('<iframe name="ifr" height="0" width="0" style="position: absolute; border:0px; width:0px; height:0px"><\/iframe>')
function GetParam(name) //Thanks to http://www.cryer.co.uk/resources/javascript/script8.htm for this function
{
var start=location.search.indexOf("?"+name+"=");
if (start<0) start=location.search.indexOf("&"+name+"=");
if (start<0) return '';
start += name.length+2;
var end=location.search.indexOf("&",start)-1;
if (end<0) end=location.search.length;
var result='';
for(var i=start;i<=end;i++)
{
var c=location.search.charAt(i);
result=result+(c=='+'?' ':c);
}
return unescape(result);
}
var paramCount=1; var index=location.search.indexOf('@'); while (index>0)
{
paramCount++;
index=location.search.indexOf('@',++index);
}
if (location.search!='')
{
function docwrite_to_div(which)
{
document.write(GetParam(which))
}
}
function include_using_iframe(where,what)
{
location.replace('?'+where+'='+escape(frames['ifr'].document.documentElement.innerHTML))
}
function include_not_using_iframe(where,what)
{
location.replace('?'+where+'='+escape(what))
}
function load_data(url)
{
frames['ifr'].location.replace(url)
}
</script>
Usage in non-IE:
Code:
<!--Document.writing a string, for instance: some data, to a div having id="div1". The string must be surrounded by appropriate quotation marks. To verify that this really is document.write (not innerHTML), modify the string by putting some javascript in it. You'll see that the javascript works on the page.-->
<a href="javascript: void(0)" onclick="include_not_using_iframe('div1','some data')">include inner data</a>
<div id="div1" style="background: silver; width: 200px"><script type="text/javascript">docwrite_to_div('div1')</script></div>

<!--Document.writing an external file, for instance: flexmenu.html (a menu offered by DynamicDrive), to a div having id="div2". Inclusion is done via Ajax. The functions in the external file are automatically transferred to the main page during inclusion, which proves that this really is document.write (not innerHTML). The placeholder for the request-string is external_data, which must not be surrounded by quotation marks (of course). We can repeatedly click on the link to include the file without losing the exernal function(s). Or we can put the external file in different divs by repeating the lines below on the page while changing the id of the div. -->
<a href="javascript: void(0)" onmousedown="HttpRequest('flexmenu.html')" onmouseup="include_not_using_iframe('div2', external_data)">include via ajax</a>
<div id="div2" style="background: silver; width: 200px"><script type="text/javascript">docwrite_to_div('div2')</script></div>

<!--Document.writing an external file, for instance: flexmenu.html, to a div having id="div3". Inclusion is done via a hidden iframe. The functions in the external file are automatically transferred to the main page during inclusion, which proves that this really is document.write (not innerHTML). We can repeatedly click on the link to include the file without losing the exernal function(s). Or we can put the external file in different divs by repeating the lines below on the page while changing the id of the div. -->
<a href="javascript: void(0)" onmousedown="load_data('flexmenu.html')" onmouseup="include_using_iframe('div3')">include via iframe</a>
<div id="div3" style="background: yellow; width:400px"><script type="text/javascript">docwrite_to_div('div3')</script></div>
Usage in IE / Google Chrome:
Same as above, but if we have scripts in the external page(s), IE will rewrite the pages to something we cannot use (safety measure). We can solve the problem in a cross-browser way by moving the scripts written down in the head of the external page(s) to the head of the main page. If the external page(s) also have scripts in the body, there may be a problem as to where to put them in the main page. Note also that, except for document.writing strings given in the main page itself, this will not (always) work locally (on your hard disk) when you're using IE or Google Chrome. But there's no problem on the Internet.

Address bar:
This method for including content may produce very long lines in the address bar.

Removing the data:
We can remove included data by doing something like:
Code:
<a href="javascript: void(0)" onclick="include_not_using_iframe('remove','')">Remove data</a>
<div id="remove" style="background: silver; width: 200px"><script type="text/javascript">docwrite_to_div('remove')</script></div>
What do we actually update?
If we use the technique described on this page, we don't update parts of the page but the whole page, to which content is added via the scripts and HTML above. That probably explains why adding content to a div is a little bit slow (especially in IE). But the advantage of the technique is that any external file can be repearedly added to the page. That's not always the case if we use other methods for including content. The flexmenu, for instance, cannot repeatedly be included on the page with preservation of code, or even included once via a simple onclick, unless we change the flexmenu-script in a specific way, see this thread.
===
DEMO here.

EDIT:
W'd better replace the occurrences of href=... above with something like style="cursor: pointer; text-decoration: underline" because using href mistakenly creates a new page in Firefox if used online.

===
Arie Molendijk

Submit "Deferred document.write" to del.icio.us Submit "Deferred document.write" to StumbleUpon Submit "Deferred document.write" to Google Submit "Deferred document.write" to Digg

Updated 10-31-2011 at 06:05 PM by molendijk (Correction)

Tags: None Add / Edit Tags
Categories
JavaScript & Ajax

Comments