【问题标题】:Modernizr Yepnope Css FallbackModernizr Yepnope Css 后备
【发布时间】:2013-06-29 16:50:46
【问题描述】:

我正在使用 CDN 加载 Bootstrap.css。 我的问题是如何检查 CDN 引导程序是否已加载/找到。 如果不是,则加载本地 Boostrap。

这是 Jquery 回退..

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

这就是我加载 Modernizr 而不是 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>

我不知道如何检查 css 是否已加载..就像我对 modernizr 和 Jquery 所做的那样..

提前谢谢...

【问题讨论】:

    标签: modernizr yepnope


    【解决方案1】:

    Stoyan Stefanov has had a Pure JS solution for this for some time now,实际上不久前刚刚获得更新。查看链接以了解详细的细分。

    但是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!')
                    }
                }
            }
        }
    ]);
    

    【讨论】:

    • 对此进行测试的注意事项:CDN 非常快,并且该文件已被缩小,因此加载速度非常快。 JSFiddle 和 CodePen 显示“已加载!”马上。制作和运行本地 HTML 文件会有更好的效果。
    • 这是一个很好的答案。只是它使用了自定义检查,因此在这方面,不妨使用fallback.io 之类的框架。但鉴于答案明确指出 Modernizr 没有原生解决方案,我想它值得赏金吗?
    • 是的,我试图尽可能忠实于最初的问题,但自 2013 年以来发生了很多变化。曾经伟大的 YepNope 已经贬值了。因此,Modernizr 将在下一个版本中放弃它。 Modernizr 仍然没有原生解决方案。所以我假设 OP 仍然想使用 Modernizr,所以我选择了使用纯 JS 检查的解决方案,而不是使用另一个库的方向。但可以肯定的是,我不能决定我是否应该得到赏金,那就由社区来决定:)
    • 好吧。就个人而言,我觉得没有其他答案可以比这个更好,我得到了答案。赏金。非常感谢您的努力!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多