6

I use yepnope.js as a resource loaded. I want to execute code in my JS module only when all the dependencies for that module have been loaded. I do not want to load JS dependencies that already been loaded.

Suppose, I have dependencies D1.js and D2.js. I tried

yepnope({
    load: ['D1.js', 'D2.js],
    complete: function() {
        //execute my code here
    }
});

That works, but, resources are loaded every time, even if they were already loaded before.

If I do multiple tests like that:

yepnope([{
    test: $().d1,
    nope: 'D1.js'
},
{
    test: $().d2,
    nope: 'D2.js'
}]);

It's not clear where to put the overall completed function -- the one that runs after all the resources have been loaded.

Is it possible to do this with yepnope, or do I need to use a different component?

Thanks.

user1044169
  • 2,686
  • 6
  • 35
  • 64

2 Answers2

4

Let's say you need to conditionally load jquery.js, jquery.jgrowl.js, and jquery.powertip.js. You'd expect the following code to work:

yepnope([{
  test: typeof(window.jQuery) === 'undefined' || 
        jQuery.fn.jquery.match(/^1\.[0-9]+/) < 1.7,
  yep: '//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js'
},
{
  test: typeof(window.jQuery) === 'undefined' 
        || typeof(window.jQuery.fn.jGrowl) === 'undefined',
  yep: ['//cdnjs.cloudflare.com/ajax/libs/jquery-jgrowl/1.2.12/jquery.jgrowl.min.js',
        '//cdnjs.cloudflare.com/ajax/libs/jquery-jgrowl/1.2.12/jquery.jgrowl.css'],
  complete: function() {
    console.log('completed loading jGrowl (should fire first, or not at all)');
  }
},
{
  test: typeof(window.jQuery) === 'undefined' 
        || typeof(window.jQuery.fn.powerTip) === 'undefined',
  yep: ['//cdnjs.cloudflare.com/ajax/libs/jquery-powertip/1.1.0/jquery.powertip.js', 
        '//cdnjs.cloudflare.com/ajax/libs/jquery-powertip/1.1.0/jquery.powertip.min.css'],
  complete: function() {
    console.log('completed loading powertip'); 
    jQuery.jGrowl("Growling!");
  }
}
]);

However, if this runs on a page where jquery.powertip.js is already loaded, but jquery.jgrow.js is not, this will throw an error, due to the 'complete' callback being fired right away, instead of when all the files are done loading.

The following fiddle demonstrates this bug with yepnope 1.5.4: http://jsfiddle.net/dergachev/HHxK2/

Note also that in the current trunk (master branch) of yepnope, this bug goes away. It's probably related to the following tickets (which were never backported to 1.5.4):

Dergachev
  • 348
  • 3
  • 6
3

The callbacks are run after the corresponding scripts are executed (not just loaded). All the scripts run in order, so if you put a callback or a complete property on the last object, it'll run last.

Alex Sexton
  • 10,401
  • 2
  • 29
  • 41
  • Alex, I am still running into issues with using multiple conditions where the complete method is "attached" to the last condition. It appears if the last condition is TRUE, but "preceding" conditions are FALSE, the complete method doesn't wait and is executed before all the scripts from "false" conditions are loaded. Is that expected? Is that a bug? Thanks. – user1044169 Sep 13 '12 at 16:13
  • Alex, can you please also comment on my earlier statement about yepnope's "load" property: "That works, but, resources are loaded every time, even if they were already loaded before.". Is that really a correct assumption? During the lifetime of a page, if I try loading the same .JS resource via the "load" property, will the file be physically downloaded multiple times? Thanks. – user1044169 Sep 13 '12 at 16:21
  • If a test is `false` it doesn't load the scripts. That's nearly the entire functionality of yepnope ;) -- As for the `load` property, we do have some checking to not load scripts twice, but I don't suggest building a solution that relies entirely on that feature as you'll probably get lost other places. – Alex Sexton Sep 13 '12 at 19:38