Reputation: 11829
I am using the fancybox jquery plugin and I am trying to defer the javascript to the end of page loading
<html>
<head>
</head>
<body>
content
/*bottom of body*/
<script src="jquery-1.8.3.min.js" type="text/javascript"></script>
<script type="text/javascript" src="jquery.fancybox-1.3.4/fancybox/jquery.fancybox-1.3.4.pack.js" ></script>
<script type="text/javascript">
$(document).ready(function() {
$(".example3").fancybox({
'transitionIn' : 'none',
'transitionOut' : 'none'
});
});
</script>
</body>
</html>
At this point the plugin works but the javascript is not deferred. Then I change the script to
<script defer="defer" type="text/javascript">
window.onload=function(){
var mycode;
mycode=document.createElement("script");
mycode.type="text/javascript";
mycode.src="jquery.fancybox-1.3.4/fancybox/jquery.fancybox-1.3.4.pack.js";
document.getElementsByTagName("head")[0].appendChild(mycode);
}
</script>
like I read here, but then the plugin sometimes work, sometimes it doesn't work. According to google pagespeed I still need to defer the jquery-1.8.3.min.js script. If I defer it the same way, google pagespeed seems ok with it, but then the plugin doesn't work at all.
How am I supposed to do this?
Complete solution based on Jamed Donnelly's answer:
I removed all .js scripts from the head. Then I added this just before the tag:
<script>
(function() {
function getScript(url,success){
var script=document.createElement('script');
script.src=url;
var head=document.getElementsByTagName('head')[0],
done=false;
script.onload=script.onreadystatechange = function(){
if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
done=true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
getScript("jquery-1.8.3.min.js",function(){
getScript("jquery.fancybox-1.3.4/fancybox/jquery.fancybox-1.3.4.pack.js", function() {});
getScript("myCustomScript.js", function() {});
});
})();
</script>
I created a file myCustomScript.js:
$(document).ready(function(){
$(".example3").fancybox({
'transitionIn' : 'none',
'transitionOut' : 'none'
});
});
And that's all.
Upvotes: 0
Views: 1129
Reputation: 128791
What I've been using for a while now is:
(function() {
function getScript(url,success){
var script=document.createElement('script');
script.src=url;
var head=document.getElementsByTagName('head')[0],
done=false;
script.onload=script.onreadystatechange = function(){
if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
done=true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
getScript("whatever1.js",function(){
getScript("whatever2.js", function() {});
});
})();
I'll have a dig to try and find where I got this from.
Edit: No luck on finding the source of this, but it's very similar to this article on CSS Tricks.
In your case you'd do something like:
getScript("jquery-1.8.3.min.js",function(){
getScript("jquery.fancybox-1.3.4/fancybox/jquery.fancybox-1.3.4.pack.js", function() {});
getScript("myCustomScript.js", function() {});
});
Where myCustomScript.js
is a file containing your document ready handler. This basically loads jQuery, then once that's loaded it then loads the plugin and your script.
Upvotes: 1
Reputation: 119847
Never rely on defer
as it is not supported cross-browser. I suggest you load the scripts at the bottom, just before </body>
with libraries loaded first (that would be what you did in the first place).
Upvotes: 0