views:

398

answers:

3

I want to give a minimal js code to random websites so that they can add a widget.

The code needs to run after the main page loads and include a parameter with the domain name. ( I don't want to hardcode it)

One option is to add this code just before the </body> (so It will run after the page loads):

<script type="text/javascript" id="widget_script">  
    document.getElementById('widget_script').src=location.protocol.toLowerCase()+"//mywebsite.com/?u="+encodeURIComponent(window.location.host);     
</script>

This works in IE but not in Firefox. I see with Firebug that the src property is created correctly but the script from my site is not loaded.

My question is : what is the best way to do that ? (preferably by putting minimal lines on the header part.)

To further clarify the question: If I put a script on the header part, how do I make it run after it is loaded and the main page is loaded? If I use onload event in my script I may miss it because it may load after the onload event was fired.

+1  A: 

You probably want to be implementing the non-blocking script technique. Essentially instead of modifying the src of a script, you're going to create and append a whole new script element.

Good write up here and there are standard ways to do this in YUI and jQuery. It's quite straightforward with only one gotcha which is well understood (and documented at that link).

Oh and this:

One option is to add this code just before the </body> (so It will run after the page loads):

...is not technically true: you're just making your script the last thing in the loading order.

annakata
Thanks for the referral!This technique seems to be an overkill and I'm not sure about browser compatibility.My goal is not to load quicker but to run after the page loads to access info on the original page
Nir
I know: but this technique solves your problem as well. As far as xbrowser goes, the only catch is that firefox has a strange timer issue which is what the setTimeout part solves. It could be that you don't even need that though.
annakata
+1  A: 

Why not use the getScript method of jQuery to do the loading? If you don't want to be dependant on jQuery, you can trace through the source to learn how they tackled it.

Viewing a widely used library is always going to show you solutions to problems you didn't know you had. For example, you can see how jQuery manages to generate a callback when the script is loaded, and how it avoids a purported memory leak in IE.

Paul Dixon
the OP doesn't actually say he's using jQuery...
annakata
See 2nd sentence!
Paul Dixon
Well I know, but you started with "why not", and the tracing bit is going to give you the answer I linked to and Aleris wrote out :)
annakata
Actually, looking at a widely used library like jQuery will reveal even more, such as how they handle post-load callbacks and a purported IE memory leak. Will add that to answer...
Paul Dixon
Thanks. I don't use jQuery.
Nir
+1  A: 

You can try to statically include the script with document.write (is an older technique and not recommended to use as it can cause problems with more modern libraries):

var url = location.protocol.toLowerCase() + 
    "//mywebsite.com/?u="+encodeURIComponent(window.location.host);
document.write('<script src="', url, '" type="text/javascript"><\/script>');

Or with dynamically created DOM element:

var dynamicInclude = document.createElement("script");
dynamicInclude.src = url;
dynamicInclude.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(dynamicInclude);

Later edit:

To ensure the script is run after onload this can be used:

var oldWindowOnload = window.onload; 
window.onload = function() {
    oldWindowOnload(); 
    var url = location.protocol.toLowerCase() + 
        "//mywebsite.com/?u="+encodeURIComponent(window.location.host);
    var dynamicInclude = document.createElement("script");
    dynamicInclude.src = url;
    dynamicInclude.type = "text/javascript";
    document.getElementsByTagName("head")[0].appendChild(dynamicInclude); 
}

I do not believe it can be shorter than this, apart from shorter variable names :)

Aleris
Thanks for the answer. How can I make sure the script I'm loading will run after the page loaded without a bunch of code that chains to the onload function and then do your code?For #2:
Nir
scripts automatically execute their source when created - the way to make sure this happens after onload is to run the script element creation block on an onload trigger
annakata