I've spent some time browsing the multitude of blogs and discussions around dynamically loading scripts, and although there are a lot of very informative and ready-made solutions as it were, I prefer to work through a solution in an attempt to understand the approaches.
In doing so, I've come across an issue with Opera (9.64 in this instance) which perhaps someone could shed some light on.
Put simply, I have a list of scripts to load when the page loads. I keep a count of the number of scripts, and as each script is loaded (readyState / onload) increment another count. When the number of scripts loaded match the total, a method in one of the loaded scripts is called.
This approach appears to be fine in IE/Firefox/Safari, but in Opera the load event is triggered (readyState = loaded) but the loaded scripts do not appear to have executed as the methods are not available. I have read about some implementation differences in Opera relating to script execution deferral and was wondering if this a possible cause? I've seen timers etc. used in similar scripts for Safari but would like to know if this is the cause of this behavior in Opera.
A sample page illustrating what I'm attempting is available at the following URI: Opera test
The main script is attached below. Any suggestions would be welcome.
Thanks,
Baps.
Code:
var scripts = {
"test1.js" : "test1",
"test2.js" : "test2",
"test3.js" : "test3"
}
var totalCount = 0;
var loadCount = 0;
window.onload = function() {
for(var i in scripts){
totalCount++;
addScript(i, scripts[i], function(){ isLoaded(); });
}
}
function isLoaded(){
if(loadCount == totalCount){
test.msg();
test1.msg();
test2.msg();
test3.msg();
}
}
function addScript(src, id, fn){
var s = document.createElement('script');
s.src = src;
s.id = id;
s.type = 'text/javascript';
if (s.readyState){
s.onreadystatechange = function(){
if (s.readyState == "loaded" || s.readyState == "complete"){
s.onreadystatechange = null;
loadCount++;
fn();
}
};
} else {
s.onload = function(){
loadCount++;
fn();
};
}
document.getElementsByTagName('body')[0].appendChild(s);
}
var test = {
msg : function(){ alert("test script"); }
}
Is this specific to 9.64? I've used Opera as my main browser since v7 and never had any issues with events (except for the annoying habit in Opera of dialogue boxes occasionally failing to interrupt scripts as they really should).
Is this specific to 9.64? I've used Opera as my main browser since v7 and never had any issues with events (except for the annoying habit in Opera of dialogue boxes occasionally failing to interrupt scripts as they really should).
I'm not sure. Is there any way to test with multiple versions without VM'ing them?
Originally Posted by Sterling Isfine
Try applying the src after installing the handler.
The order of the src appears to have no effect. I'm assuming the script is not "fetched" until it's added to the live DOM?
Originally Posted by rnd me
try replacing "fn();" with "window.setTimeout(fn, 35);"
This does indeed solve the problem. Could you possibly explain why? Is the 35 an arbitrary number? I.e. would a very large script require a larger timeout?
Bookmarks