I'm loading an external script that uses callback function, which returns some specific data. If this data is not received error should be displayed.
Here is the code I've 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 that can go wrong with the script, so I naturally added an onerror event. This on error event actually fires if you change host name or domain of the script to something non-existent.
However, if you only make changes to the url of the script, it can still connects to the server and fires an onload event instead. My callback function will not be called for those invalid requests, so I added an onload handler as well.
Now the problem is, if all loaded normally and data was returned, it will fire both, callback function and onload. I have noticed that callback function is triggered before the onload and set the visitors_loaded variable so that the handler function is only called once.
So far it works perfectly in JS fiddle and my offline site but I wonder if this is an expected behavior? Will that json_callback function always have precedence before the onload handler?
https://jsfiddle.net/5sfk9ht5/4/
Higher-Order Functions(HoF) and Callback Functions(CB) are different. Higher-Order Functions(HoF): A function that takes another function(s) as an argument(s) and/or returns a function as a value. Callback Functions(CB): A function that is passed to another function.
We need callback functions because many JavaScript actions are asynchronous, which means they don't really stop the program (or a function) from running until they're completed, as you're probably used to. Instead, it will execute in the background while the rest of the code runs.
The onload in javascript is compatible with loading elements like CSS files, images, script files, etc. within a web page. The onload events are one of the most used and primarily part of the <body> tag. Another advantage is the ability of the onload event to deal with web cookies.
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action. The above example is a synchronous callback, as it is executed immediately.
Will that json_callback function always have precedence before the onload handler?
If the external script calls my_callback
synchronously then yes.
The scripting
section in the official html5 specification describes how these things are supposed to work. The specification is quite general and has to deal with a lot of details conserning encoding, CORS, ignore-destructive-writes counter
and so on. But for this question we don't care about these specifics.
In step 4 there is a note:
Note: This is where the script is compiled and actually executed.
And in step 7 the load
event is fired:
fire a simple event named load at the script element.
So the specification defines that the load
event is always fired after the script has been executed.
As you see the specification also tells us why the onerror
event is not fired if you change the URL. The error
event is only created if loading the script fails. But all requests to https://api.clicky.com/api/stats/
return a HTTP 200 status. The invalid URLs return XML and thus a SyntaxError is thrown. But this does not cause the onerror
handler to be triggered.
As others have mentioned if the callback is called asynchronously they can call your callback after the onload
event. But I don't see a reason why they would do this async in your external script.
onload in older IE might not work for you 'onload' handler for 'script' tag in internet explorer, if you want to run all browsers you might need something like this https://jsfiddle.net/e287523t/2/ and should work for all
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 defining my_callback and calling addScript
my_callback = function(someData) {
alert(JSON.stringify(someData));
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With