2015-07-05 22 views
0

如果我使用下面的腳本:CDN回退的相關腳本

  • jQuery的
  • jQuery驗證
  • jQuery驗證不顯眼的
  • 引導

引導和jQuery驗證要求的jQuery而jQuery Validation Unobtrusive需要jQuery驗證,所以我們有相互依存的腳本。我看到所有的回退腳本是這個樣子:

(window.jQuery || document.write('<script src="/bundles/jquery"><\/script>')); 
($.validator || document.write('<script src="/bundles/jqueryval"><\/script>')); 
($.validator.unobtrusive || document.write('<script src="/bundles/jqueryvalunobtrusive"><\/script>')); 
($.fn.modal || document.write('<script src="/bundles/bootstrap"><\/script>')); 

的問題是,如果我使用的ajax.aspnetcdn.com CDN和失敗,則第一行會導致jQuery來從本地加載,但接下來的三行代碼將在執行之前和錯誤之前執行,因爲$未定義。

是否有標準的方式來處理這些類型的相互依存的後退腳本?我環顧四周,無法找到處理此類場景的資源。

UPDATE

我回答了這個問題,盡我所能,但我仍然在尋找人們如何處理這個問題的答案。

回答

1

依靠另一個第三方腳本似乎矯枉過正,但我​​發現了Fallback.jsYepNope.js可能能夠處理這種情況。我不確定CDN正常​​工作的日常情況對性能的影響。更多信息here

我也有一展身手,在寫我自己的實現:

JavaScript的回退

(function (document, fallbacks) { 

    var check = function (fallbacks, i) { 
     if (i < fallbacks.length) { 
      var fallback = fallbacks[i]; 
      if (fallback.test()) { 
       check(fallbacks, i + 1); 
      } 
      else { 
       var script = document.createElement("script"); 
       script.onload = function() { 
        check(fallbacks, i + 1); 
       }; 
       script.src = fallback.src; 
       document.getElementsByTagName("body")[0].appendChild(script); 
      } 
     } 
    } 
    check(fallbacks, 0); 

})(document, [ 
    { test: function() { return window.Modernizr; }, src: "/js/modernizr.js" }, 
    { test: function() { return window.jQuery; }, src: "/js/jquery.js" }, 
    { test: function() { return $.validator; }, src: "/js/jquery-validate.js" }, 
    { test: function() { return $.validator.unobtrusive; }, src: "/js/jquery-validate-unobtrusive.js" }, 
    { test: function() { return $.fn.modal; }, src: "/js/bootstrap.js" }, 
    { test: function() { return window.Hammer && window.Hammer.VERSION; }, src: "/js/hammer.js" }, 
    { test: function() { return window.Zepto; }, src: "/js/bootstrap-touch-carousel.js" } 
]); 

CSS回退

使用元標籤的想法,從被 '借'新的ASP.NET 5 MVC 6框架。

(function (document, fallbacks) { 

    var metas = document.getElementsByTagName("meta"); 

    for (var i = 0; i < fallbacks.length; ++i) { 
     var fallback = fallbacks[i]; 

     for (j = 0; j < metas.length; ++j) { 
      var meta = metas[j]; 
      if (meta.getAttribute("name") == fallback.metaName) { 
       if (!fallback.test(meta)) { 
        var link = document.createElement("link"); 
        link.href = fallback.href; 
        link.rel = "stylesheet"; 
        document.getElementsByTagName("head")[0].appendChild(link); 
       } 
       break; 
      } 
     } 

    } 

})(document, [ 
    { 
     // metaName - The name of the meta tag that the test is performed on. The meta tag must have a class from the 
     //   relevant stylesheet on it so it is styled and a test can be performed against it. E.g. for 
     //   font awesome the <meta name="x-font-awesome-stylesheet-fallback-test" class="fa"> meta tag is 
     //   added. The 'fa' class causes the font awesome style to be applied to it. 
     metaName: "x-font-awesome-stylesheet-fallback-test", 
     // test - The test to perform against the meta tag. Checks to see if the Font awesome styles loaded 
     //  successfully by checking that the font-family of the meta tag is 'FontAwesome'. 
     test: function (meta) { return meta.style.fontFamily === "FontAwesome"; }, 
     // href - The URL to the fallback stylesheet. 
     href: "/css/font-awesome.css" 
    } 
]);