Forum Moderators: open

Message Too Old, No Replies

Delay loading of document.write script

Anyone know a way to do it?

         

londrum

2:34 pm on Aug 6, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Hello. I was just wondering if anyone knows a way to achieve this:

i have to load a few external .js scripts on my site which write stuff to the page using document.write. of course, this slows down the page display a little bit, so i have rewritten most of them to use innerHTML instead, which can do the same thing after the page has finished loading.

but unfortunately there is one script that originates from another site, so i cant get rid of the document.write. and when you try and delay it until the rest of the page is written it doesn't work (because it needs to write stuff halfway up the page).

what i need to do is fetch that script as normal, but delay the document.write until the rest of the page has finished loading.

my first idea was to grab the content of the script as a string, and replace document.write with the innerHTML bit instead, but i cant get that to work.

Fotiman

4:27 am on Aug 7, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Include that script in a container element just before your closing body tag, then just reposition that container using CSS.

rocknbil

5:15 pm on Aug 8, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



what about

window.onload = function() {
//do the writes here?
};

Fotiman

6:35 pm on Aug 8, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@rocknbil, you can't call document.write after the page has finished loading... it will replace the current document.

londrum

6:57 pm on Aug 8, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



yup, i need a way to replace document.write with innerHTML

i had a go at moving the block to the end of the HTML and repositioning with CSS, but that means i have to move the block outside of its parent, and i cant position it relatively anymore. if i position it absolutely then i cant get the cells to resize properly with the content around it.

Fotiman

7:27 pm on Aug 8, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Alternatively, perhaps you can move the node or clone it to elsewhere in the DOM. For example, suppose you have this:


<html>
<head>
<style type="text/css">
#external {
background: #ccc;
}
</style>
</head>
<body>
<div id="placeholder"></div>
<div id="content">...</div>
<div id="external">
<script>
document.write('External Content');
</script>
</div>
<script>
(function () {
var placeholder = document.getElementById('placeholder'),
external = document.getElementById('external');
placeholder.appendChild(external);
})();
</script>
</body>
</html>

astupidname

8:38 am on Aug 9, 2011 (gmt 0)

10+ Year Member



Hijack document.write:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Some Title</title>
<script type="text/javascript">

//addThisEvent -utility function for setting event listeners
//cross-browser, and preserving 'this' within attachEvent.
//el may be a single html element as a DOM object, or the window object,
//type should be string name of event type ('on' prefix not required, so 'mouseover' or 'onmouseover' works fine)
//fn should be a function to set as an event handler
function addThisEvent(el, type, fn) {
var ename = type.replace(/^on/i, '');
if (el.attachEvent) { //IE
el.attachEvent('on'+ ename, function () {
return fn.call(el, window.event); //fixes IE's fudging of 'this' in attachEvent
});
} else if (el.addEventListener) { //Standard
el.addEventListener(ename, fn, false );
} else {
el["on"+ename] = fn;
}
}

//this variable will receive all strings from within
//document.write calls, which will no longer work
//as we are hijacking document.write below
var STRINGS_TO_WRITE__AAARRRGHHH = '';

document.write = function () {
var i = 0,
a = arguments,
len = a.length;
for (; i < len; i++) {
STRINGS_TO_WRITE__AAARRRGHHH += a[i];
}
};

addThisEvent(window, 'load', function () {
document.getElementById('someDivId').innerHTML = STRINGS_TO_WRITE__AAARRRGHHH;
});

</script>
</head>
<body>
<div id="someDivId" style="background-color:beige;"></div>
<script type="text/javascript">
document.write('hello world<br>', 'I belong in the beige div');
</script>
</body>
</html>

If anybody's wondering, how to post formatted code on webmasterworld [webmasterworld.com]
Do not copy formatted code on webmasterworld from IE, use other browser such as Firefox.


Note this could have drawbacks if other scripts than the one you wish to corral use document.write also, but there are ways around that too if it's a problem...
Also note, the script with the document.write could now actually be in the head section instead, so long as it's after the script where we hijack document.write

londrum

8:24 pm on Aug 9, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



that function looks like it might do the trick, cheers

Fotiman

8:46 pm on Aug 9, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I don't know... something about overwriting a native method of the document object rubs me the wrong way. If it were me, I would just use the appendChild method to move the nodes around.

astupidname

8:36 am on Aug 10, 2011 (gmt 0)

10+ Year Member



I think I'm in agreement with Fotiman here actually now. Hijacking document.write does have it's potential pitfalls. Though I agree it's bad to overwrite native methods in general, document.write is the only one I would ever consider (and actually did this before for a page of mine which used to receive stuff from Yahoo via document.write that I wished to alter before it was presented on page. Worked great til they closed/changed that feed...). It can be easily put back properly if wanted by doing:

document.oldStupidFunction = document.write;
document.write = function (){/*what I want it to do*/};
document.write('some crap');
document.write = document.oldStupidFunction;
document.oldStupidFunction = null;
delete document.oldStupidFunction;
alert(document.oldStupidFunction);//'undefined', as though we were never here... shhh..

But now all things considered, if you can accomplish what you need via Fotiman's appendChild example I'd also say do that, it's much simpler and should do the trick just fine. Was merely presenting a possible option. Plus I wanted to say STRINGS_TO_WRITE__AAARRRGHHH :)