Thursday, August 28, 2008

Appending to event functions in javascript

So, Google Answers is a Google Product (feature?) that has come and gone, evidently. I was looking up some information on how to do something specific with JavaScript and Googled into a JavaScript question that someone had posted, asking how to go about "Appending to event functions in javascript".

Well, this was not what I was doing, specifically, but along the same vein of what I was looking into. Anyway, I was sad to see that I knew the answer and yet, with Google Answers closed down, I wasn't able to post a response, even though no one had answered the question.

Anyway, I am posting a code snippet below for anyone who is interested in adding javascript function calls (or, for that matter, other javascript executable statements) to the document.body.onload after the page has started loading.

This comes with no guarantee or warranty, but may be fun to play around with. Please note that the alert that says "This fires first" fires ON LOAD, as do the others, but it fires before the "page has loaded" alert, because it is being PREpended to the top of the list of things to do on load. This allows you to include something later in the file that needs to be done before other things. Using this same concept, one could build a more elaborate set of functions that allow you to insert statements into the list of statements to be executed in a specific, desired order, sort the statements in some fashion or specifically delete or modify a single statement, but I don't know if that would really serve any true purpose. This is more of an academic exercise.

The code:
<html>
<head>
<title>Changing Onload via JavaScript</title>
<script>
function onload1()
{
alert("page has loaded");
}
function addedFunction()
{
alert("Added Function successfully");
}

function prependOnload(statement)
{
insertOnload(statement, true);
}
function appendOnload(statement)
{
insertOnload(statement, false);
}
function insertOnload(statement, isPrepend)
{
var oldOnload = document.body.onload+"";
var startOfOldStatements = oldOnload.indexOf("{")+1;
var endOfOldStatements = oldOnload.lastIndexOf("}")-1;
var instructions = oldOnload.substring(
startOfOldStatements, endOfOldStatements);
var newOnload = (isPrepend)?
(statement+instructions):(instructions+statement);

newOnload = new Function(newOnload);
document.body.onload = newOnload;

}

</script>

</head>
<body onload="onload1();">
<script>
appendOnload("addedFunction();");
prependOnload("alert('This fires first');");
</script>
</body>
</html>


Notes on the code:
The main work-horse here is insertOnload(). The first thing it does is gets the current value of onload as it stands. This is a function, not a string, so in order to manipulate it, we have to force a cast to string, hence the +""... add a string to something and it becomes a string. Sneaky, no?

With the contents in a string form, we then peel off the function definition, leaving us with a list of instructions (again, as a big ole chunk of text). We can easily either add our new statement to the beginning (statement+instructions) or to the end (instructions+statement).

Now that we have the statements that we want executed, we have to create a new Function containing this new list and then assign it to document.body.onload and we're done.

No comments: