views:

392

answers:

4

I have a JS script that will be hosted on my server and that others will embed in their html, i.e.

...<code for http://yoursite.com />
<script type="text/javascript" src="http://mysite.com/awesome.js" />
...<code for http://yoursite.com />

My script surfaces an object with a bunch of properties accessible for use as a javascript Object(), i.e.

<script type="text/javascript">
//From http://mysite.com/awesome.js
alert(Awesome.Name);
</script>

Due to the load time variance, it seems I need to signal that the "Awesome" object in my script is ready. I need this to stand on its own, so no dependencies on specific JS frameworks.

Do I need to publish my own custom JS event, or does the simple fact that my script is loaded get captured by one of the existing page-level events? How else should I be doing this?

UPDATE: as a point of reference, if I include the JS in an HTML page running from "http://mysite.com", the Awesome object is available and populated. When the JS file is included from another domain, the object is undefined at runtime.

+1  A: 

If your script needs the DOM to be loaded before your object is instantiated, you should look at some frameworks and see how they handle this, then implement it in your code. If you don't need the DOM to be loaded, then I would let the user worry about the timing of using your object based on when it is loaded. Generally, your object should be available to be be used as soon as your script has been loaded, which means that the object ought to be available right after the script tag that includes it.

tvanfosson
Thanks. "your object should be available to be be used as soon as your script has been loaded" was my understanding, but I'm not seeing this behavior. There's a delay in having the object fully populated/declared.
jro
A: 

A). You realise that script requests are blocking? Are you ok with this or do you want to work around that, because the answer to your question depends on it.

B). Bare bones bulletproof and simple mechanism is to call a specified method which you can guarantee exists on the page. Let that methods implementation be up to the user to do what it will. Lots of other ways exist but we'd need to know what exactly the lifecycle and intent of your code is to recommend anything.

annakata
Thanks. No, not aware that script requests were blocking. I'm not sure I follow your suggestion, so any help is great.Is your suggestion that my library, which consists of an object with properties, to call a method on the page? It's simply a data container, intended for other objects to access.
jro
+5  A: 

The javascript content of <script> tags is executed procedurally, so this

<script type="text/javascript" src="http://mysite.com/awesome.js" />
<script type="text/javascript">
    alert(Awesome.Name);
</script>

will only alert the contents of Awesome.Name if found in any previous script tag.

To understand if everything has been fully loaded on the page, you have to use the DOMContentLoaded, for firefox, and "onreadystatechange" for ie. Also you can simply check the load event on the window object if you don't care about checking the DOM (could be easier).

if ( document.addEventListener ) {
    document.addEventListener( "DOMContentLoaded", function(){
         doSomething();   
    }, false );
} else if ( document.attachEvent ) { // IE        
    document.attachEvent("onreadystatechange", function(){
        if ( document.readyState === "complete" ) {
            doSomething();
        }
    });
}
Luca Matteis
Ah good, DOMContentLoaded. So, what's the simple answer for IE, Safari, Opera? ;-)
jro
@jro: if you can get away with waiting for images to load use `window.onload`; you may also add a script as last element to `body`; if you don't want the delay of the former/don't like the latter, use a framework or implement the workarounds (doScroll, defer, onreadystatechange,...) yourself
Christoph
@Luca: only adding an 'onreadystatechange' listener is not enough: you have to check the value of `readyState`, otherwise your function might get executed even if the document is still incomplete!
Christoph
Christoph: yes you're right, I totally forgot to add that.
Luca Matteis
@Luca: yeah, cross-platform event handling is a hassle :( btw: afaik in IE, `document.readyState = complete` fires after external resources have been loaded as well, ie there's no gain over `window.onload` except that the event fires directly before the `onload` listeners...
Christoph
@Luca: you put the `readyState`-check one level too high: it must be inside the listener
Christoph
GODDAMN , yes, next time ill just copy and paste from a framework.
Luca Matteis
A: 

Anything accessible in the global scope can be accessed through the window scope. Hence, you could use this:

if (window["Awesome"] != null) { /* do something */ }
Piskvor