Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modernizr Yepnope Css Fallback

I'm using a CDN to Load Bootstrap.css. My question is how can i check if CDN bootstrap was loaded/found. And if it wasn't, then load local Boostrap.

Here's Jquery fallback..

    <script type="text/javascript">
        Modernizr.load([
            {
                load: '//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.1/jquery.min.js',
                complete: function () {
                    if ( !window.jQuery ) {
                        Modernizr.load([
                            {
                                load: config.js + 'vendor/jquery-1.10.1.min.js',
                                complete: function () {
                                    console.log("Local jquery-1.10.1.min.js loaded !");
                                }
                            }
                        ]);
                    } else {
                        console.log("CDN jquery-1.10.1.min.js loaded !");
                    }
                }
            }
        ]);
    </script>

And this is how i load Modernizr than Css:

    <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
    <script type="text/javascript">
    if (typeof Modernizr == 'undefined') {
        document.write(unescape("%3Cscript src='" + config.js + "/vendor/modernizr-2.6.2-respond-1.1.0.min.js' type='text/javascript'%3E%3C/script%3E"));
        console.log("Local Modernizer loaded !");
    }
    </script>

    <script type="text/javascript">
        Modernizr.load([
        {
            load: config.css + "bootstrap.css",
            complete: function () {
                console.log("bootstrap.css loaded !");
            }
        },
        {
            load: config.css + "responsive.css",
            complete: function () {
                console.log("responsive.css loaded !");
            }
        },
        {
            load: config.css + "icons.css",
            complete: function () {
                console.log("Fontello icons.css loaded !");
            }
        },
        {
            load: config.css + "icons-ie7.css",
            complete: function () {
                console.log("Fontello icons-ie7.css loaded !");
            }
        },
        {
            load: config.css + "animation.css",
            complete: function () {
                console.log("Fontello animation.css loaded !");
            }
        }
        ]);
    </script>

I have no idea how i could check if the css was loaded.. just like i did with modernizr and Jquery..

Thanks in advance...

like image 934
JonnyDevv Avatar asked Nov 13 '22 02:11

JonnyDevv


1 Answers

Stoyan Stefanov has had a Pure JS solution for this for some time now, which actually just got an update not too long ago. Check out the link for an in depth breakdown.

But style.sheet.cssRules will only be populated once the file is loaded, so by checking for it repeatedly with a setInterval you are able to detect once your CSS file is loaded.

d = document;
d.head || (d.head = d.getElementsByTagName('head')[0]);

var style = d.createElement('style');
style.textContent = '@import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"';

var fi = setInterval(function() {
    try {
        style.sheet.cssRules;
        console.log('loaded!');
        clearInterval(fi);
    } catch(e){
        console.log('loading...');
    }
}, 10);

d.head.appendChild(style);

YepNope acknowledges the use of this technique, though they note in their documentation that YepNope's "callback does not wait for the css to actually be loaded".

Plus with YepNope's recent depreciation, let's move onto to a solution that integrates with Modernizr (who will no longer be including YepNope in their software), but does not utilize any of Modernizr's libraries, since they still do not have a native solution. Offirmo combines a couple of neat techniques from Robert Nyman and Abdul Munim to let Modernizr know the CSS is actually loaded.

We start with the following function, which allows us to get the CSS property of an element:

function getStyle(oElm, strCssRule){
    var strValue = "";

    if (document.defaultView && document.defaultView.getComputedStyle){
        strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
    } else if (oElm.currentStyle){
        strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
            return p1.toUpperCase();
        });
        strValue = oElm.currentStyle[strCssRule];
    }

    return strValue;
}

Then we use the following funtion to create an hidden DOM element to test out CSS properties within:

function test_css(element_name, element_classes, expected_styles, rsrc_name, callback) {
    var elem = document.createElement(element_name);
    elem.style.display = 'none';
    for (var i = 0; i < element_classes.length; i++){
        elem.className = elem.className + " " + element_classes[i];
    }
    document.body.appendChild(elem);

    var handle = -1;
    var try_count = 0;
    var test_function = function(){
    var match = true;
    try_count++;
    for (var key in expected_styles){
        console.log("[CSS loader] testing " + rsrc_name + " css : " + key + " = '" + expected_styles[key] + "', actual = '" + get_style_of_element(elem, key) + "'");
        if (get_style_of_element(elem, key) === expected_styles[key]) match = match && true;
        else {
            console.error("[CSS loader] css " + rsrc_name + " test failed (not ready yet ?) : " + key + " = " + expected_styles[key] + ", actual = " + get_style_of_element(elem, key) );
            match = false;
        }
    }

    if (match === true || try_count >= 3){
          if (handle >= 0) window.clearTimeout(handle);
          document.body.removeChild(elem);

          if (!match) console.error("[CSS loader] giving up on css " + rsrc_name + "..." );
          else console.log("[CSS loader] css " + rsrc_name + " load success !" );

          callback(rsrc_name, match);
        }

        return match;
    }

    if(! test_function()){
        console.info("" + rsrc_name + " css test failed, programming a retry...");
        handle = window.setInterval(test_function, 100);
    }
}

Now we can reliably know, within Modernizr, if our CSS is ready to go:

Modernizr.load([
    {
        load: { 'bootstrap-css': 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css' },
        callback: function (url, result, key){
            //THIS IS OUR TEST USING THE ABOVE FUNCTIONS
            test_css('span', ['span1'], {'width': '60px'}, function(match){
                if (match){
                    console.log('CDN Resource Loaded!');
                } else {
                    console.log('Fallback to local resource!')
                }
            }
        }
    }
]);
like image 91
Madness Avatar answered Nov 29 '22 05:11

Madness