Tutorial - Combining Window Events

Do you have two or more scripts that just won't seem to work together, but they work fine by themselves? Chances are this is because the scripts are using window event handlers. This tutorial explains how to get your scripts working without sacrificing one of your cool new scripts.



What are these "events" and how do they work?

An event is when something happens. When you click a form button; that is an event. When you hover a link; that is an event. When the page finishes loading; that is an event. There are many events for almost every element in your page. Newer browsers support more scriptable events than older browsers such as Netscape 4.x or IE3.x. Generally, each element has default event handlers associated with them. For example, a link's onmouseover event causes the target URL to display in the status area of the browser by default. Even though you didn't specifically set the mouseover event, this is what the browser does.

With Javascript, you can make something else happen when one of these events occur. Then, once the browser finishes executing the command you set for this event, you can either make the browser continue doing what it was intending to do or stop right there.

So far, I've only talked about events on HTML elements, but you can also assign commands to other events such as when the page is done loading (window.onload), or when the user moves the mouse around the page (document.onmousemove), or when the user presses a mouse button over the page (document.onmousedown). There are a bunch, but I'm sure you get the idea.

Many scripts assign event handlers if they need to keep track of mouse position, or "trap" when someone clicks the mouse (even which button was clicked), or execute something when the page is fully loaded.



How do I change an event?

Since the majority of the events you will work with will be the onload event, I will focus primarily on this event, but keep in mind these examples work for other events too. I will explain a few other ones toward the end of the tutorial, but you will see the method is basically the same.

You can assign an event handler in 2 ways: in the HTML element or in the script itself.

Assigning an event handler in an HTML element is pretty easy. Let's say you want to execute a javascript function called init() when the page is done loading (this is a very common thing to do). You could add the event handler in the BODY tag like this:

<BODY onload="init()">

This is perfectly ok, but let's say you have a script (such as a menu system) that needs to be loaded in every page. You would have to copy the bulk of the javascript code where it needs to and then copy the extra code into the BODY tag. This creates an extra step. It would be a little easier to just make the script do it all and avoid the extra step. Well, it can, and there are 3 slightly different ways to do it in script form (1st being most common, 3rd being least common):
Method 1:
<script language="javascript">

function init(){
...code...
}

window.onload=init;
</script>
Basically, you define the function and then assign that function name to the event handler. You'll notice that the parenthesis () were left off the end of the function name, this is intended. Adding the parenthesis will cause the function name to be assigned to the event instead of executing it; not really what you want I don't think.

Just copy all the script and it automagically causes the function called init() to run only once the page is finished loading!
Method 2:

Instead of calling a predefined function with the window.onload event handler, you can also assign a "nameless" function directly like this:
<script language="javascript">

window.onload=function(){
...code...
}

</script>
In this example, you don't predefine a named function, you just assign the function body to the event.
Method 3:

Or, you can use the Function() contructor like in this example:
<script language="javascript">

window.onload=new Function("...code...");

</script>
This last one is a little more difficult to use since all commands must be in string form. This can cause problems if you need to use other quotes in the command list; you have to escape them or use single quotes. Plus it isn't quite as easy to see what is going on unless the command string is short and simple. I don't use this version very often for this reason. I usually use either of the first 2 ways.

Even though assigning commands to an event in the BODY tag is totally fine, I will be focusing more on using solutions which require editing the javascript code. After the tutorial is done, you may know enough of what is going on to utilize the BODY tag if you prefer.



OK, I think I understand the basics of events and event handlers, but how do I get 2 scripts which use these methods to work together?

If you have two scripts in the same page that assign commands to an event only the last event assignment the browser "sees" will work. So, only one of the scripts will work right. You have to combine all the commands that each script needs into one event handler.

For the sake of example, I will create two bogus scripts, create arbitrary function names, and color code each script to make it easier to see what is happening. All code for script #1 will be in green, while all code for script #2 will be in red.

The first script needs to call the function start() and the second script needs to call the function init(). I will use window.onload=function(){...} to combine them below. Note that you do put the parenthesis after the function name when it is inslde the function body.
Script #1:
<script language="javascript">

function start(){
...code for script #1...
}

window.onload=start;

</script>
Script #2:
<script language="javascript">

function init(){
...code for script #2...
}

window.onload=init;

</script>
Result:
<script language="javascript">

function start(){
...code for script #1...
}

function init(){
...code for script #2...
}

window.onload=function(){
start();
init();
}

</script>
Another slightly different way would be to create another function, give it an arbitrary name, put all the other commands in it, then assign it to the window.onload event.
Script #1:
<script language="javascript">

function start(){
...code for script #1...
}

window.onload=start;

</script>
Script #2:
<script language="javascript">

function init(){
...code for script #2...
}

window.onload=init;

</script>
Result:
<script language="javascript">

function start(){
...code for script #1...
}

function init(){
...code for script #2...
}

function initAll(){
start();
init();
}

window.onload=initAll;

</script>
If one or more of the scripts you want to use has the event handler in the BODY HTML tag, you can still move it to into javascript code. See the example below:
Script #1:
<script language="javascript">

function start(){
...code for script #1...
}

</script>

<body onload="start()">
Script #2:
<script language="javascript">

function init(){
...code for script #2...
}

window.onload=init;

</script>
Result:

<script language="javascript">

function start(){
...code for script #1...
}

function init(){
...code for script #2...
}

window.onload=function(){
start();
init();
}

</script>

<body>
Notice how I removed the event from the BODY tag and put it into the script.
There are a few more possible combinations, but I think you get the point.



But the javascript code that contains the event handler(s) are in external ".js" files. How can I combine these?

Putting javascript into a js file sometimes is the most efficient way to integrate a script into many pages; you only have to add the one line of code that loads the file. This is especially useful for menu navigation systems. Plus, once the .js file is loaded, successive pages often start faster because the file is stored in the browser's cache.

Incidently, a ".js" file is basically pure javascript code, without any HTML tags, stored in a plain text file, whose filename has the .js file extension.

These files are great, but does pose a problem if you have two of them that assign functions to an event. You could simply apply the methods above to combine them, but it may be hard to keep track of which file had the proper initialization code. Plus, you might not want the same two scripts running in every page.

The easiest way would be to remove just the event handler code from each file, paste it directly into your HTML page inside a set of javascript tags instead, and then combine the event handlers using the methods explained earlier. This way, each page controls the initialization of the code depending on which .js file you loaded.


All you've talked about is "window.onload" events, how about "mouse" or "keyboard" events?

The examples above work basically the same way for most types of event handlers. The same rules apply. The only thing that may snag you up in dealing with mouse or keyboard events is the fact that there are event properties relating to the target element that may not be returned to the handling function. It depends on what the script author is doing.

So, even if you modify the code just like the examples above, the scripts still may not work. It doesn't mean you edited incorrectly, it just means the code is probably too complex. Plus, older Netscape 4.x browsers require an additional step when trapping mouse and keyboard events. Unfortunately, these types of scenarios are beyond the scope of this discussion and require a little more know-how than simple cut-n-paste. Most sophisticated menu or mouse following scripts probably fall under this category.

However, if these event handlers are calling simple functions that do not need the element reference for the "this" keyword, then the procedures above should work (don't worry if you don't know what the "this keyword" is). You could always give it a try. Good luck!