423,688 Members | 1,864 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 423,688 IT Pros & Developers. It's quick & easy.

how can i tell when a .js file is loaded?

P: n/a
If I follow the steps on
http://www.dhtmlcentral.com/tutorial...ials.asp?id=11 to add .js
files to a document on demand, let's say by <body onload="blah();">, how
can I reliably tell that it has been loaded?

BTW, I'm doing this for several .js files (and I don't always know how
many I'll be loading), so I need to check them all.

If I code for IE, I can check all the document.scripts[n].readyState
values (not being "uninitialized" or "loading"), but is there a single
method I can use that's better?

Could I do this using document.getElementsByTagName("script"), for example?

Thanks,

Ian
Jul 23 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Ian Richardson wrote:
If I follow the steps on
http://www.dhtmlcentral.com/tutorial...ials.asp?id=11 to add .js
files to a document on demand, let's say by <body onload="blah();">, how
can I reliably tell that it has been loaded?
Add a variable in your .js file and check for its existence.

http://www.hikksworld.com/loadJSFiles/index.html

Is a chart that shows where you can/can not load .js files on the fly,
and what methods work in which browsers. As you can see, its not that
easy to load one dynamically and know its going to work.
BTW, I'm doing this for several .js files (and I don't always know how
many I'll be loading), so I need to check them all.
Why not just document.write the script tags then?

If I code for IE, I can check all the document.scripts[n].readyState
values (not being "uninitialized" or "loading"), but is there a single
method I can use that's better?
Again, document.write'ing the script tags is simpler and less error
prone than trying to dynamically load them.
Could I do this using document.getElementsByTagName("script"), for example?


Perhaps. Never tried it.
--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/
Jul 23 '05 #2

P: n/a
Randy Webb wrote:
Ian Richardson wrote:
If I follow the steps on
http://www.dhtmlcentral.com/tutorial...ials.asp?id=11 to add .js
files to a document on demand, let's say by <body onload="blah();">,
how can I reliably tell that it has been loaded?

Add a variable in your .js file and check for its existence.


That's precisely what I didn't want to do. I could check for the typeof
of a function in each file but not all the files have a function in them.
http://www.hikksworld.com/loadJSFiles/index.html

Is a chart that shows where you can/can not load .js files on the fly,
and what methods work in which browsers. As you can see, its not that
easy to load one dynamically and know its going to work.


....and from my own tests this is not totally correct.
BTW, I'm doing this for several .js files (and I don't always know how
many I'll be loading), so I need to check them all.

Why not just document.write the script tags then?


The document has already loaded, I must be able to force the extra .js
files into the head. This technique works for loading them, using
Mozilla, IE and Opera (the only browsers I'm interested in), but it's
the verification that they've loaded which is the issue.
If I code for IE, I can check all the document.scripts[n].readyState
values (not being "uninitialized" or "loading"), but is there a single
method I can use that's better?
<snip>
Could I do this using document.getElementsByTagName("script"), for
example?

Perhaps. Never tried it.


Has anyone else?

Thanks,

Ian
Jul 23 '05 #3

P: n/a
Ian Richardson wrote:
Randy Webb wrote:
Ian Richardson wrote:
If I follow the steps on
http://www.dhtmlcentral.com/tutorial...ials.asp?id=11 to add .js
files to a document on demand, let's say by <body onload="blah();">,
how can I reliably tell that it has been loaded?


Add a variable in your .js file and check for its existence.

That's precisely what I didn't want to do. I could check for the typeof
of a function in each file but not all the files have a function in them.


Its a lot more efficient to do a one time append to each .js file and
add a last line than it is to attempt to determine by typeof a function
or a variable. Either way you are trying to detect something in an
external file. The advantage of the append is that you know exactly what
exists in every single file, so its only one simple test.

A second alternative, although I have never tested it to see how/when it
will break, is something like this:

<script type="text/javascript" src="someFile.js">
var notLoaded = true;
</script>

Not sure exactly how it works if it can't find someFile.js or it doesn't
load.

http://www.hikksworld.com/loadJSFiles/index.html

Is a chart that shows where you can/can not load .js files on the fly,
and what methods work in which browsers. As you can see, its not that
easy to load one dynamically and know its going to work.

....and from my own tests this is not totally correct.


What part is "not totally correct"? If you are agreeing that you can't
always load one dynamically, then I agree. If you are saying that my
stats page is wrong, I have to beg to differ as it was tested in each
browser thats listed (not all were done by me, if there is erroneous
data there, please let me know OS/Browser/Rev so I can update it.)

BTW, I'm doing this for several .js files (and I don't always know
how many I'll be loading), so I need to check them all.


Why not just document.write the script tags then?

The document has already loaded, I must be able to force the extra .js
files into the head. This technique works for loading them, using
Mozilla, IE and Opera (the only browsers I'm interested in), but it's
the verification that they've loaded which is the issue.


Again, the simplest, easiest way to maintain is to add a very unique
named variable in every .js file and then check for that variables
existence.

<--snip-->
--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/
Jul 23 '05 #4

P: n/a
Randy Webb wrote:
Ian Richardson wrote:
Randy Webb wrote:
Ian Richardson wrote:

If I follow the steps on
http://www.dhtmlcentral.com/tutorial...ials.asp?id=11 to add .js
files to a document on demand, let's say by <body onload="blah();">,
how can I reliably tell that it has been loaded?


Add a variable in your .js file and check for its existence.


That's precisely what I didn't want to do. I could check for the
typeof of a function in each file but not all the files have a
function in them.

Its a lot more efficient to do a one time append to each .js file and
add a last line than it is to attempt to determine by typeof a function
or a variable. Either way you are trying to detect something in an
external file. The advantage of the append is that you know exactly what
exists in every single file, so its only one simple test.


This suggestion seems simplest, and least likely to break. If it's more
convenient, use a global array in <head>:

var javascript_sources = [];

and at the end of each separately sourced file:

javascript_sources.push('some_id_for_this_js_sourc e');

You can check each separate file by its id, or just the length of the
array if you know how many to expect.

-- hj
Jul 23 '05 #5

P: n/a
Howard Jess wrote:
Randy Webb wrote:
Ian Richardson wrote:
Randy Webb wrote:

Ian Richardson wrote:

> If I follow the steps on
> http://www.dhtmlcentral.com/tutorial...ials.asp?id=11 to add
> .js files to a document on demand, let's say by <body
> onload="blah();">, how can I reliably tell that it has been loaded?
<snip>
That's precisely what I didn't want to do. I could check for the
typeof of a function in each file but not all the files have a
function in them.

<snip>
This suggestion seems simplest, and least likely to break. If it's more
convenient, use a global array in <head>:

var javascript_sources = [];

and at the end of each separately sourced file:

javascript_sources.push('some_id_for_this_js_sourc e');

You can check each separate file by its id, or just the length of the
array if you know how many to expect.


Again, this is "add something to the end of each file". It's not the
approach I want as:

a) Internet Explorer has it's own proprietary solution; i.e.
periodically checking the readyState property. This works a treat for IE.

b) There simply must be a proper way of doing this using the DOM.

I don't particularly want to go down the other kludge route of using the
XMLHttpRequest object in Mozilla (and its activeX alternative in IE),
then set the .text property of the script object I'm inserting into the
HEAD of the document to the returned responseText string. The reason for
this is the browser appears to freeze while it's fetching the resource.

I've tried creating an object and then setting its .onload property, but
this seems to be fired by Mozilla immediately rather than once the
object is loaded.

I should point out that my target browsers are latest versions of IE and
Mozilla, and possibly Opera (now that 7.50 is half usable... but that's
for another time!)

Is there another solution?

Thanks,

Ian
Jul 23 '05 #6

P: n/a
Ian Richardson wrote:

<--snip-->


Again, this is "add something to the end of each file". It's not the
approach I want as:

a) Internet Explorer has it's own proprietary solution; i.e.
periodically checking the readyState property. This works a treat for IE.
The AOL browser uses a shell of IE but you might want to be careful
trying to group it with IE as it does not provide all the functionality
that IE does. The first two that come to mind are the external and
onbeforeunload, IE supports both but AOL supports neither. Never tested
it to see whether it handles readystate the same as IE does or not.
I mention AOL because it has a very large user base and most people tend
to group it with IE but its not always safe to do that.
b) There simply must be a proper way of doing this using the DOM.
Not that I have ever found, that works reliably cross-browser.

I don't particularly want to go down the other kludge route of using the
XMLHttpRequest object in Mozilla (and its activeX alternative in IE),
then set the .text property of the script object I'm inserting into the
HEAD of the document to the returned responseText string. The reason for
this is the browser appears to freeze while it's fetching the resource.

I've tried creating an object and then setting its .onload property, but
this seems to be fired by Mozilla immediately rather than once the
object is loaded.

I should point out that my target browsers are latest versions of IE and
Mozilla, and possibly Opera (now that 7.50 is half usable... but that's
for another time!)

Is there another solution?


Since you are including Opera 7 in the mix (I had originally considered
HTTPRequest as a possible solution but O7 doesn't support it at all)
then you are better off starting with O7 and making it work, then going
up the chain to Mozilla and then to IE.

This page:
<URL: http://members.aol.com/justhikk/index.html >
works somewhat like you are implying yours does. Even if it doesn't, it
still has the same problem. How to know when the .js file is loaded.

Parts of it work, parts of it do not. It was something I was working on
2+ years ago and ran out of time to tinker with it anymore and have put
it on the shelf to work with on a later date.

Basically, what happens is every single menu item (with the exception of
the music menu) has a .js file associated with it that is nothing but
data. The functions are in the main page. You choose an option, it
loads the data file, then changes the page.

Change Option>Load JS File>Change Page.

The problem was "How to know when the JS file loaded so I could call the
function that changed the page" and in the end, the solution was very
simple. I put the function call at the end of the JS file.

Change Option>Load JS File>JS File Calls function>Function changes Page.

I honestly do not remember if that solution came to me on my own or if I
got it from this group. I beat my head on the same wall that you are
running into, needing to know when the file had finished loading, and
the simplest, most cross-browser method is indeed to append one or two
lines to each .js file and have the js file itself tell the main page
"Hey, Im loaded now", whether its via a variable, a function call or
some other method.

So please take it from my own experience and headaches that you aren't
going to find a cross-browser approach that works better.

Hope this helps.

PS The above page is the one that actually led to me making the page I
gave the URL for before:
<URL: http://www.hikksworld.com/loadJSFiles/index.html >
Where I was trying to figure out how to even dynamically load the .js
file itself.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/
Jul 23 '05 #7

P: n/a
Randy Webb wrote:
Ian Richardson wrote:

<--snip-->


Again, this is "add something to the end of each file". It's not the
approach I want as:

a) Internet Explorer has it's own proprietary solution; i.e.
periodically checking the readyState property. This works a treat for IE.

The AOL browser uses a shell of IE but you might want to be careful
trying to group it with IE as it does not provide all the functionality
that IE does. The first two that come to mind are the external and
onbeforeunload, IE supports both but AOL supports neither. Never tested
it to see whether it handles readystate the same as IE does or not.
I mention AOL because it has a very large user base and most people tend
to group it with IE but its not always safe to do that.


I wasn't aware of that, but then again I would never pollute a computer
with the AOL software in order to determine such a thing.
b) There simply must be a proper way of doing this using the DOM.

Not that I have ever found, that works reliably cross-browser.


Damn, damn, damn, etc...
I don't particularly want to go down the other kludge route of using
the XMLHttpRequest object in Mozilla (and its activeX alternative in
IE), then set the .text property of the script object I'm inserting
into the HEAD of the document to the returned responseText string. The
reason for this is the browser appears to freeze while it's fetching
the resource.

I've tried creating an object and then setting its .onload property,
but this seems to be fired by Mozilla immediately rather than once the
object is loaded.

I should point out that my target browsers are latest versions of IE
and Mozilla, and possibly Opera (now that 7.50 is half usable... but
that's for another time!)

Is there another solution?

Since you are including Opera 7 in the mix (I had originally considered
HTTPRequest as a possible solution but O7 doesn't support it at all)
then you are better off starting with O7 and making it work, then going
up the chain to Mozilla and then to IE.


The Opera reference was more wishful thinking than anything else; I can
leave Opera out of the equation for a while because I've got some really
nasty problems with it. (As an aside, and probably for the Opera forums,
these mainly involving how it royally buggers up with multiples of one
or more table rows within a tbody, where the .display class of the tbody
is toggled.)
This page:
<URL: http://members.aol.com/justhikk/index.html >
works somewhat like you are implying yours does. Even if it doesn't, it
still has the same problem. How to know when the .js file is loaded.
The only difference is this page loads the .js files on user demand,
where mine loads them from a script (which will eventually be
dynamically generated depending on settings read from another server)...
but we both have the same problem!

<snip>
The problem was "How to know when the JS file loaded so I could call the
function that changed the page" and in the end, the solution was very
simple. I put the function call at the end of the JS file.
I can see that "putting something at the end of the file" is the
solution I'm being pushed towards, but there must be a better way.

<snip>
So please take it from my own experience and headaches that you aren't
going to find a cross-browser approach that works better.


I can see I'll have to think more about this...

Thanks,

Ian
Jul 23 '05 #8

P: n/a
I don't often reply to myself, but...

OK, I've now got a working solution for the following circumstances:

1. If typeof document.readyState != "undefined", use setInterval() to
periodically go through document.scripts[] to check that nothing has the
Internet Explorer readyState attribute set to a value of either
"uninitialized" or "loading"... otherwise,

2. Whenever I want to create a new script object (with a .id attribute)
for insertion into the head, I create an element in an array, e.g.
loaded[id] = false, and I have the .onload attribute set to call a
function which sets loaded[this.id] = true. I can then use setInterval()
periodically go through this array to check that nothing is still set to
false.

Now I'm creating a script object and inserting it into the head... but
if the check for readyState fails, my code is hoping for a series of
onload events which - in the case of Opera and other lesser browsers -
may never happen. If I set the .text attribute of this script object,
will the contents of the script.src I'm loading destroy it, prepend or
append itself to the .text?

Thanks,

Ian
Jul 23 '05 #9

P: n/a
Ian Richardson wrote:
I don't often reply to myself, but...
Replying to oneself is fine, as long as you don't start having
conversations with yourself :)

OK, I've now got a working solution for the following circumstances:

1. If typeof document.readyState != "undefined", use setInterval() to
periodically go through document.scripts[] to check that nothing has the
Internet Explorer readyState attribute set to a value of either
"uninitialized" or "loading"... otherwise,
That, as you imply, is the IE-only approach, and it may well work.

But it also reminded me of why I tried to avoid the createElement
approach to start with.

<URL: http://www.hikksworld.com/loadJSFile...ementTest.html >

If you use the buttons and create new elements, then watch the textarea.
The document will continue to grow and grow and grow, dynamically every
time a script element is created. Internet Explorer supports changing
the src of a script element, if it has an ID attribute:

document.getElementById('scriptID').src = someOtherFile;

<script type="text/javascript" id="scriptID"></script>

And then you don't end up with several script elements.
2. Whenever I want to create a new script object (with a .id attribute)
for insertion into the head, I create an element in an array, e.g.
loaded[id] = false, and I have the .onload attribute set to call a
function which sets loaded[this.id] = true. I can then use setInterval()
periodically go through this array to check that nothing is still set to
false.

Now I'm creating a script object and inserting it into the head... but
if the check for readyState fails, my code is hoping for a series of
onload events which - in the case of Opera and other lesser browsers -
may never happen. If I set the .text attribute of this script object,
will the contents of the script.src I'm loading destroy it, prepend or
append itself to the .text?


The test page above shows that it will ignore the .text property,
entirely, if it has a src attribute, even if the file can't be loaded.
Its 7am here, and I have to leave for work soon. That test page is one I
threw together real quick, to show the .src and .text properties. When I
get back home tonight, I will add some more buttons and more tests to
show all the possibilities and post back about it.
When the s.src line is commented out of the function in the page above,
you get the alert (tested in IE and Mozilla) Opera won't give the alerts
at all.....

I still think the most efficient, cross-browser, method is what I
proposed to start with. Appending a variable or function call to each
..js file that will tell the page its loaded. It gives you the sole step
of adding the call, but the advantages far out-weigh it, in that it will
work in any browser that can load a .js file, without all the checking
of readyStates and onloads.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/
Jul 23 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.