Forum Moderators: open

Message Too Old, No Replies

external js file is not loaded when instantiated - how to fix

a problem i found and fixed

         

httpwebwitch

4:52 pm on Nov 13, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I recently had a problem with a javascript that was used to power a whole DHTML sliding menu thing. It's a pretty big script, with lots of browser sniffing and building of arrays and objects for the menu. It was included as a *.js file in the <HEAD> of the page, using a normal linking method that usually works:

<script src='Menus.js'>

On some machines, (seemingly independent of the browser or OS), we would consistently get a javascript error. My script defined an object, which was initialized - so i thought - once the entire page had loaded.

<body onLoad='init()'>

After several experiments, I found that the javascript was loading concurrently with the page HTML, but that the 'onLoad' event was triggered before the javascript had finished loading.

If you have a big javascript file, it is possible that the page it's included on will download faster than the page itself. The commands in your mainline (or triggered by onLoad) may try to execute before the script is defined. Splat! Javascript error.

The solution was pretty simple. Instead of linking to an external JS file, I put the whole script into <script> tags and included it directly in the <HEAD> using a SSI.

in essence, I replaced this code:

<script language="JavaScript" type='text/javascript' src="Menus.js"></script>

with this code:

<?php include_once("Menus.js");?>

... and the problem went away. My example uses PHP syntax, but you can do the same thing with any server-side language. The SSI is handy because you can still keep that script in an external file. If you don't have server scripting, you can accomplish the same thing by cutting and pasting the script directly into the <HEAD> of your page.

Here's hoping this helps anyone who has experienced similar problems.

YorkshireSteve

7:21 pm on Nov 13, 2003 (gmt 0)

10+ Year Member



What if someone's using your menu on a static site? With no PHP or SSI available? ;o)

What if the included JavaScript file had a return value or something, at the bottom of the script? Your HTML document only finishes loading when it's got to the bottom of the JavaScript...

You could also set a variable at the bottom of the included file (

finished = true
), and in your main HTML document's head, create a loop which could test
while(finished == false) ...
Only when it gets to the end of the JavaScript code and sets finished to true would it proceed to load the HTML page.

My JavaScript is poor, so my ideas probably won't work! Just some ideas though. :o)

Steve.

httpwebwitch

5:10 pm on Dec 5, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What if someone's using your menu on a static site? With no PHP or SSI available? ;o)

Well, I am using this on MY site, and PHP *is* available. It makes no difference on the browser-end. But for someone having the same problem on a static site, just cut-and-paste the javascript into the <head>, there's no need to use SSI if you don't have it.

Your HTML document only finishes loading when it's got to the bottom of the JavaScript...

That's the point of my warning - They don't load sequentially, they load concurrently. The HTML loads itself and triggers the onLoad event regardless of the status of the included script. Therefore, you can't rely on it to start processes that need to wait until the script is loaded. It is a common practice to do this:


<body onLoad="init();">

... and that isn't reliable when you have a large external javascript containing your init() function.

What if the included JavaScript file had a return value or something, at the bottom of the script?

That idea might work in some situations. If the included javascript sets a flag upon loading, then I can check for that flag at the onset of any event that should initiate a javascript method.


<a href="#" onMouseOver='if(isloaded){dostuff();}'>

I haven't tested that theory, but it would be worth a try.