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.

3 Answers 3

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

<script src="mujScript.js" defer></script>

New contributor
Vit BLOG is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

1 Comment

This is the equivalent to defer="defer", which the original question clearly demonstrates they know about. As other answers indicate, this isn’t reliable—or, at least, wasn’t when the question was first asked.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.