Conditional Loading of CSS files based on test condition in JQuery plugin

3k views Asked by At

I'm looking for the best approach to conditionally load some files based on a specific set of conditions.

I have three CSS files and two javascript files which I'm currently loading like so:

<link href="core.min.css" rel="stylesheet" type="text/css"> 
<link href="add_regular.min.css" rel="stylesheet" type="text/css"> 
<link href="add_retina.min.css" rel="stylesheet" type="text/css"> 
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery-plugin.min.js"></script>

As is evident the fourth file is JQuery and the fifth is my JQuery plugin. Inside the JQuery plugin are a series of functions that are like tests e.g. isMobile, isRetina, isPhone, etc. However, let's focus on isRetina.

What I am trying to accomplish is as follows:

  1. Load JQuery and my JQuery Plugin first
  2. Use isRetina function inside my JQuery plugin to check whether the device has a retina display
  3. Load core.min.css
  4. Load add_regular.min.css if not Retina display, or load add_retina.min.css if Retina display

Currently I'm loading all three CSS files and I wouldn't want to do that because I've got a bunch of other CSS files and I want to load them as my JQuery plugin determines which one is best as per my above example. For example, I might have a phone.min.css that I would want to load after I do another test using my plugin's isPhone function.

I'm considering using YepNope and doing something like this:

<script type="text/javascript" src="yepnope.min.js"></script>
<script>
yepnope([{
    load: ['jquery.min.js', 'jquery-plugin.min.js'],
    test : $.myplugin.isRetina(),
    yep  : ['core.min.css', 'add_retina.min.css'],
    nope : ['core.min.css', 'add_regular.min.css'],
    complete : function(){
       //my jquery plugin constructor here
       $(selector).myplugin(options);
    }
}]);
</script>

However, even if the above approach is the correct one, I am not sure how to implement document.ready, as my plugin's constructor needs to run only when the DOM is ready.

I would like some ideas on how I can pull this off using YepNope or any other solution.

Cheers.

3

There are 3 answers

0
ObiHill On BEST ANSWER

I was just going over the JQuery Docs for .ready(), and apparently $(function(){}); is equivalent to $(document).ready(function() {}); (I'm not sure how I'm just discovering this #ScratchingMyHead).

I also saw this being used in a YepNope Tutorial on NetTuts+: http://net.tutsplus.com/tutorials/javascript-ajax/easy-script-loading-with-yepnope-js/.

So I guess my earlier code becoming what you see below should solve the problem:

<script type="text/javascript" src="yepnope.min.js"></script>
<script>
yepnope([{
    load: ['jquery.min.js', 'jquery-plugin.min.js', 'core.min.css'],
    test : $.myplugin.isRetina(),
    yep  : 'add_retina.min.css',
    nope : 'add_regular.min.css',
    complete : function(){
       //my jquery plugin constructor added to JQuery DOM Ready Stack
       $(function(){
           $(selector).myplugin(options);
       });           
    }
}]);
</script>

I will test this out and remove this if it doesn't work.

5
Paul S. On

I am not sure how to implement document.ready, as my plugin's constructor needs to run only when the DOM is ready.

There are two relevant events

window.addEventListener('load', function () {
    // code runs when document+resources have finished loading
});

and

document.addEventListener('DOMContentLoaded', function () {
    // code runs when document has finished parsing, but before resources loaded
});

If you wait for either of these events before importing jQuery, I'm not sure what effect it will have on jQuery's inbuilt $(document).ready / similar.

That said, you do have the option of checking document.readyState === 'complete' before attaching listeners, to see if you should invoke straight away.

3
Rob Schmuecker On

Not sure if I understand you correctly but this should work.

Include this by default:

<link href="core.min.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery-plugin.min.js"></script>
<script type="text/javascript">
    yepnope([{
        load: ['jquery.min.js', 'jquery-plugin.min.js'],
        test : $.myplugin.isRetina(),
        yep  : ['core.min.css', 'add_retina.min.css'],
        nope : ['core.min.css', 'add_regular.min.css'],
        complete : function(){
           //my jquery plugin constructor here
           $(selector).myplugin(options);
           //Remove the mask here.
        }
    }]);
    // Feel free to call ready() here
    $(document).ready(function(){
      // whatever you want here
    });
</script>

Then you can call ready() adding your specific logic according to the output of your tests. This way ready will only fire once the above has loaded and executed.