5

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

4

1 回答 1

1

Stoyan Stefanov已经为此提供了一个 Pure JS 解决方案已有一段时间了,实际上不久前刚刚得到了更新。查看链接以获取深入细分。

style.sheet.cssRules只有在文件加载后才会被填充,因此通过反复检查它,setInterval您可以检测到您的 CSS 文件是否已加载。

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 承认使用了这种技术,尽管他们在文档中指出 YepNope 的“回调不会等待 css 实际加载”。

再加上 YepNope 最近的贬值,让我们转向与 Modernizr 集成的解决方案(他们将不再在他们的软件中包含 YepNope),但不使用 Modernizr 的任何库,因为他们仍然没有本机解决方案。Offirmo结合了Robert NymanAbdul Munim的一些巧妙技术,让 Modernizr 知道 CSS 实际已加载。

我们从以下函数开始,它允许我们获取元素的 CSS 属性:

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;
}

然后我们使用以下函数创建一个隐藏的 DOM 元素来测试其中的 CSS 属性:

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);
    }
}

现在我们可以在 Modernizr 中可靠地知道我们的 CSS 是否准备就绪:

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!')
                }
            }
        }
    }
]);
于 2015-08-08T01:44:09.070 回答