30

I am working with both amq.js (ActiveMQ) and Google Maps. I load my scripts in this order

<head>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
    <title>AMQ & Maps Demo</title>

    <!-- Stylesheet -->
    <link rel="stylesheet" type="text/css" href="style.css"></link>

    <!-- Google APIs -->
    <script type="text/javascript" src="http://www.google.com/jsapi?key=abcdefg"></script>

    <!-- Active MQ -->
    <script type="text/javascript" src="amq/amq.js"></script>
    <script type="text/javascript">amq.uri='amq';</script>

    <!-- Application -->
    <script type="text/javascript" src="application.js"></script>
</head>

However in my application.js it loads Maps fine but I get an error when trying to subscribe to a Topic with AMQ. AMQ depends on prototype which the error console in Firefox says object is not defined. I think I have a problem with using the amq object before the script is finished loading. Is there a way to make sure both scripts load before I use them in my application.js?

Google has this nice function call google.setOnLoadCallback(initialize); which works great. I'm not sure amq.js has something like this.

ekad
  • 14,436
  • 26
  • 44
  • 46
Bernie Perez
  • 12,513
  • 13
  • 46
  • 55

8 Answers8

43

cross-domain scripts are loaded after scripts of site itself, this is why you get errors. interestingly, nobody knows this here.

John Doe
  • 495
  • 4
  • 2
  • 2
    Thank you for this comment. After moving my scripts to the same domain, no more issues. – BradH Sep 02 '11 at 16:05
  • 2
    Is there a mistake here (http://stackoverflow.com/questions/1307929/javascript-dom-load-events-execution-sequence-and-document-ready) at the "considerer good answer": "Javascript is guaranteed to run in the order it appears in your HTML, so just make sure your function is defined before you try to attach it to an event."? – Olivier Pons Oct 24 '11 at 20:06
  • 15
    This doesn't seem possible, since it's fairly common practice to load, say, jQuery from Google's CDN, and then have your own local scripts that require jQuery – spinn Feb 04 '13 at 10:03
  • 2
    Just tested this in recent versions of Chrome and Firefox and it's not true in either. It also contradicts MDN (see https://developer.mozilla.org/en/docs/Web/HTML/Element/script). -1; you've provided no evidence for your claim and I don't believe that it's true. – Mark Amery Dec 20 '14 at 22:18
27

Is there a way to make sure both scripts load before I use them in my application.js?

JavaScript files should load sequentially and block so unless the scripts you are depending on are doing something unusual all you should need to do is load application.js after the other files.

Non-blocking JavaScript Downloads has some information about how scripts load (and discusses some techniques to subvert the blocking).

Walter Rumsby
  • 7,435
  • 5
  • 41
  • 36
  • It's also worth looking at the [Asynchronous Module Definition](http://en.wikipedia.org/wiki/Asynchronous_module_definition) API and others that do the same thing for loading JavaScript files and other resources in parallel. – Vimes Mar 25 '14 at 16:42
9

in jquery you can use:

$(document).ready(function(){/*do stuff here*/});

which makes sure the javascript is loaded and the dom is ready before doing your stuff.

in prototype it looks like this might work

document.observe("dom:loaded", function() {/*do stuff here*/});

If I understand your problem correctly.. I think that may help..

If you don't want to rely on a lib to do this... I think this might work:

<script>
   function doIt() {/*do stuff here*/}
</script>
<body onLoad="doIt();"></body>
danb
  • 10,239
  • 14
  • 60
  • 76
7

I had a similar problem to this, only with a single script. The solution I came up with was to use addEventListener("load",fn,false) to a script object created using document.createElement('script') Here is the final function which loads any standard JS file and lets you add a "post load" script.

function addJavaScript( js, onload ) {
   var head, ref;
   head = document.getElementsByTagName('head')[0];
   if (!head) { return; }
   script = document.createElement('script');
   script.type = 'text/javascript';
   script.src = js;
   script.addEventListener( "load", onload, false );
   head.appendChild(script);
}

I hope this may help someone in the future.

cmcginty
  • 113,384
  • 42
  • 163
  • 163
3

Is there a way to make sure both scripts load before I use them?

Yes.

Put the code you want loaded last (your application.js stuff) into prototype's document.observe. This should ensure that the code will load only after prototype + other stuff is finished and ready. (If you are familiar with jQuery, this function is similar to jQuery's $(document).ready )

Alexander Elgin
  • 6,796
  • 4
  • 40
  • 50
maxsilver
  • 4,524
  • 4
  • 28
  • 24
2

AMQ depends on prototype which the error console in FireFox says object is not defined.

Do you mean that AMQ depends on the Prototype library? I can't see an import for that library in the code you've provided.

Walter Rumsby
  • 7,435
  • 5
  • 41
  • 36
2

Do you mean that AMQ depends on the Prototype library? I can't see an import for that library in the code you've provided.

Yes for ActiveMQ's javascript (amq.js) does depend on Prototype. In the amq.js it loads 3 scripts, _amq.js, behaviour.js and prototype.js.

Thanks you for your help on the JavaScript load order wrumsby. This tells me that my bug is in another castle :(

I guess I have a different problem. I also checked the js files from ActiveMQ 5.0 to 5.1 and noticed they were the same as well. Something has changed in 5.0 to 5.1 that requires a refresh for the topics to subscribe. I'll keep looking, but thanks for eliminating this possible cause.

Bernie Perez
  • 12,513
  • 13
  • 46
  • 55
0

You can also use the built in SharePoint javascript method to control the execution of your scripts;

_spBodyOnLoadFunctionNames.push("yourFunction");
Brian Scott
  • 9,221
  • 6
  • 47
  • 68