0

My question is based from this topic: Possible to defer loading of jQuery?

I used the 1st answer to that post and it works, well.. mostly. I get an "TypeError: success is not a function" in FF Firebug console, FF dev console, and Chrome dev console. I was looking to ask Dan Atkinson about his solution with the success function, but I cannot comment because of the 50 rep, so that's why this is a separate question.

Here is my current script(truncated because of some sensitive information contained):

(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('http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js', function() {
    // YOUR CODE GOES HERE AND IS EXECUTED AFTER JQUERY LOADS
    {% if template contains 'product' %}
    jQuery(document).ready(function($) {
        $("a.zoomer").fancybox({
            padding: 0,
            'titleShow': false,
            overlayColor: '#000000',
            overlayOpacity: 0.2,
            fitToView: false,
            autoSize: false,
            height: 1500
        });  
  }); {% endif %}
// script truncated
});

})();

(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.fancybox.pack.js' | asset_url }}");
getScript("{{ 'slick.min.js' | asset_url }}");
getScript("{{ 'option_selection.js' | shopify_asset_url }}");
getScript("{{ 'api.jquery.js' | shopify_asset_url }}");
getScript("{{ 'jquery.tweet.js' | asset_url }}");
getScript("{{ 'scripts.js' | asset_url }}");
getScript("{{ 'jquery.lazyload.min.js' | asset_url }}");

})();

I had much trouble trying to get my script in the {code tags} so I couldn't get the entire script to past without the post validator giving me a warning. It may be the liquid code nestled within the scripts.

Here are some screen captures of the error I receive: http://screencast.com/t/q1idygFanob http://screencast.com/t/mKpGiEPHsA

I needed to defer jQuery and all the dependent scripts in order to improve the Google page speed insights. It said that we needed to remove render blocking scripts and one of them was jQuery.

I tried to just remove success(); and that made the whole thing not work. I tried what Dan Atkinson said in his comment if(success && getClass.call(success) == '[object Function]') { success(); }, but I think I did it wrong.

Can anyone tell me what is wrong with the success(); part?

Community
  • 1
  • 1
Naruto
  • 3
  • 3

1 Answers1

0

success is the 2nd argument to getScript. But you are not supplying a 2nd argument for most of your getScript calls.

If you want the success argument to be optional, then change:

success();

to:

success && success();
Brandon
  • 38,310
  • 8
  • 82
  • 87
  • Brandon, what was wrong with @Dan-Atkinson 's approach to the success argument? `if(success && getClass.call(success) == '[object Function]') { success(); }` What you said gets rid of the error on the second script block that just referenced a bunch of external scripts. I kept the 1st block that references jQuery with just the 'success();` part. Am I correct in doing so? – Naruto Jul 11 '14 at 12:24
  • Hard to say without seeing the error you saw. Most likely you did not define `getClass`. Sure it is fine to keep it the way you have it. Though really you only need to define `getScript` once and use it for both blocks, but exactly how to do that is beyond the scope of this question... – Brandon Jul 11 '14 at 14:09