0

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.

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

I put the whole function between <script></script> tags just before the </body> tag and removed the two script lines. It's not working. Did I do something wrong? I updated my question
It's not working because jQuery will not be included until after the page has loaded, whereas your <script> tags before </body> will run beforehand. To defer the loading you'll need to create a new .js file to hold your $(document).ready(function(){ ... });.
I thought I was missing that. I am more like an html+css guy, could you help me with what you mean by that?
Create a new file called myNewFile.js and move your $(document).ready(function(){ ... }); into that file, then after calling getScript(jquery-1.8.3.min.js")... call getScript("myNewFile.js", function() {});.
Best monday ever. Thank you!
0

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).

1 Comment

But like I said, it's not always working. E.g I've moved <script src="jquery-1.8.3.min.js"></script> just before the </body> tag from the head and a script stopped working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.