In an DHTML solution I've been working on I need to tap into window.onload and append my own function in there. The code looked something like this:


<script>
function foo() { alert("foo"); }
window.onload = function() { foo(); }
</script>
... more HTML junk ...
<script>
function bar() { alert("bar"); }
window.onload = function() { bar(); }
</script>

If you run this it will only run the bar() function because it was defined last. Ideally one would want to write something like this in the second chunk of javascript:


<script>
function bar() { alert("bar"); }
window.onload = function() { foo(); bar(); }
</script>

which when you run it does both alerts but it's unfortunate that the second piece of javascript needs to know about parenting code.

My solution requires that any new work on window.onload takes whatever was there into account before. Here's the solution I came up with. It seems to work fine in Firefox (linux, windows) and Internet Explorer (windows).

What I do is that I create a variable of the current window.onload and call it like any other function. It looks like this:


<script>
function bar() { alert("bar"); }
var prev_onload = window.onload;
window.onload = function() { prev_onload(); bar(); }
</script>

The advantage here is that in the second piece of code which can come from anywhere on the server, you do not need to know anything about what happened before in the document. This makes it very convenient when writing a very modular website with widgets coming in from different places. Try it if it works on your computer

What do people think?

Comments

Post your own comment
Ian Bicking

But does it leak memory on IE? I suspect it does...

Peter Bengtsson

"suspect". I can only hope it won't. How can I test it without actually using a windows computer for more than 5 minutes?

Rob

*gasps in horror* That happens? Is there no garbage collector?

Rick Hurst

If my understanding is correct, the problem you are trying to solve is that there are various functions that need to be fired by window onload, but these are contained in various widgets and macros so you never know which ones and how many will need to be fired?

The way I would approach it is something like this:-

I would have a page variable "str_onload_functions" to store a string. There would also be a function called fn_add_onload_function_name which would append function names, (as strings, probably seperated by commas) to str_onload_functions. each time you have a widget or macro that needs to add a new window.onload function fired, you would pass it the function name as a string. Then (hmm.. this is starting to sound overcomplicated at this point!) there would be a function somewhere omnipresent called fn_execute_onload_functions that would look at str_onload_functions and if it isn't empty, split the string into an array and loop through using exec() to fire each one. then you would just have one call to window.onload which fires fn_execute_onload_functions

This way you would only be storing a string in memory... or maybe you would just add the names directly to an array so you don't need to split it up later

my two pence worth :-)

Peter Bengtsson

Just tested. This works fine in Konquerer

Jason Kummerl

You need to check if prev_onload is null.

window.onload = function() { if ( prev_onload) {prev_onload();} bar(); }

Peter Bengtsson

Are you sure, isn't window.onload always an object?

Jason Kummerl

Yes because if you have not defined window.onload before you grab is using 'var prev_onload = window.onload;' prev_onload will be null instead of a function.

www.AndrewTaylor.EU

Thank you! You helped me clarify how to perform a function on page load!

window.onload = function() { foo(); }

Your email will never ever be published.

Related posts

Go to top of the page