Javascript onload and script callback functions which takes precedence?

I am loading an external script that uses a callback function that returns some specific data. If this data is not received, an error should be displayed.

Here is the code I made:

<script> //setting initial state so that function will only work once var visitors_loaded=false; var my_callback = function( data ) { if (visitors_loaded) return 0; if (data) { //success: callback function is called and it has a proper data visitors_loaded=true; alert(JSON.stringify(data)); } else alert ('error'); //something went wrong }; </script> <script onload="my_callback(null)" onerror="my_callback(null)" src="https://api.clicky.com/api/stats/4?site_id=32020&sitekey=9a19b1a4d1171193&type=visitors&date=this-month&output=json&json_callback=my_callback"></script> 

As you can see ... many things can go wrong with the script, so I naturally added an onerror event. This error event actually fires if you change the hostname or domain of the script to something that does not exist.

However, if you only make changes to the script URL, it can still connect to the server and instead fire the onload event . My callback function will not be called for these invalid requests, so I added an onload handler.

Now the problem is that if all loaded normally and the data was returned, it will run both the callback function and the load. I noticed that the callback function runs before loading and sets the visitor_loaded variable, so that the handler function is called only once.

While it works fine in the JS script and my standalone site, but I wonder if this is the expected behavior? Will this json_callback function always take precedence over the onload handler?

https://jsfiddle.net/5sfk9ht5/4/

+6
source share
3 answers

Will this json_callback function always take precedence over the onload handler?

If an external script calls my_callback synchronously, then yes.

The scripting section of the official html5 specification describes how these things should work. The specification is pretty general and should deal with a lot of details that require coding, CORS, ignore-destructive-writes counter and so on. But for this issue we do not care about these features.

There is a note in step 4:

Note. Here the script is compiled and actually executed.

And in step 7, the load event is fired:

run a simple load named load in the script element.

Thus, the specification determines that the load event always fires after the script is executed.


As you can see, the spec also tells us why the onerror event onerror not onerror if you change the URL. The error event is error only when the script fails to load. But all https://api.clicky.com/api/stats/ requests return an HTTP 200 status. Invalid URLs return XML and thus a SyntaxError is generated. But this does not trigger the onerror handler.


As already mentioned, if the callback is called asynchronously, it can call your callback after the onload . But I see no reason why they will do this asynchronously in your external script.

+3
source

Now the problem is that if all loaded normally and the data was returned, it will run both the callback function and the load. I noticed that the callback function runs before loading and sets the users_loaded variable, so the handler function is called only once.

This is because the callback is launched from the called script from api.clicky.com

While it works fine in the JS script and my standalone site, but I wonder if this is the expected behavior?

I see what you get, a related question about what happens when the script does not work here , but I did some tests for you and here are the results.

tester.html:

 <script> var onLoadTest = function() { console.log("Onload Called!"); }; var callbacktest = function() { console.log("Called from other script!"); }; var errortest = function() { console.log("Callback OnError!"); }; </script> <script onload="onLoadTest()" onerror="errortest()" src="script.js"></script> 

script.js

 function otherScriptFunc() { //call the function in the original script callbacktest() } otherScriptFunc(); // first call to other script setTimeout(otherScriptFunc, 0); // final call to other script 

Console Log Results

 Called from other script! Onload Called! Called from other script! 
  • Your OnLoad will be called when JS finishes parsing elsewhere (async functions will do their own work). For example, otherScriptFunc(); will call before OnLoad , but setTimeout(otherScriptFunc, 0); will be called after OnLoad

  • Your OnError will only be OnError if a GET request fails. IE, the file cannot be found, or the URL cannot be resolved - nothing about what is in the file. (I tested it separately, just messed up the file name)

  • Your callback passed to another script can be called whenever it likes another script. He has a link to him and he can decide to stay on it for a while and call him later after he played. This means that it can be in an asynchronous call, waiting for data elsewhere. This means that theoretically, your onload could indeed be called before the callback, but it depends on another script, and you cannot do much of it.

Will this json_callback function always take precedence over the onload handler?

It's not about priority, it just depends on when another script decides to name it.

+2
source

onload in older IE may not work for you the onload handler for the script tag in Internet explorer , if you want to run all browsers, you need something like https://jsfiddle.net/e287523t/2/ and should work for everyone

  function addScript(fileSrc, callback) { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; script.onreadystatechange = function() { if (this.readyState == 'complete') { callback(); } } script.onload = callback; script.src = fileSrc; head.appendChild(script); } 

Then the rest is determined by my_callback and calls addScript

  my_callback = function(someData) { alert(JSON.stringify(someData)); }; 
+1
source

All Articles