[jquery] CDN이 실패 할 경우 로컬 스타일 시트 (스크립트 아님)로 대체하는 방법

CDN의 jQuery Mobile 스타일 시트에 연결 중이며 CDN이 실패 할 경우 스타일 시트의 로컬 버전으로 돌아가고 싶습니다. 스크립트의 경우 솔루션은 잘 알려져 있습니다.

<!-- Load jQuery and jQuery mobile with fall back to local server -->
<script src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
<script type="text/javascript">
  if (typeof jQuery == 'undefined') {
    document.write(unescape("%3Cscript src='jquery-1.6.3.min.js'%3E"));
  }
</script>

스타일 시트에 대해 비슷한 작업을하고 싶습니다.

<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css" />

스크립트를 링크 할 때 브라우저가 스크립트를로드 할 때와 같은 방식으로 차단하는지 여부를 확신 할 수 없기 때문에 비슷한 접근 방식을 얻을 수 있는지 확실하지 않습니다 (스크립트 태그에 스타일 시트를로드 한 다음 페이지에 삽입)?

그래서 내 질문은 : CDN이 실패하면 스타일 시트가 로컬로로드되는지 어떻게 확인합니까?



답변

브라우저 간 테스트를 거치지 않았지만 이것이 작동 할 것이라고 생각합니다. 하지만 jquery를로드 한 후에야합니다. 그렇지 않으면 일반 Javascript로 다시 작성해야합니다.

<script type="text/javascript">
$.each(document.styleSheets, function(i,sheet){
  if(sheet.href=='http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css') {
    var rules = sheet.rules ? sheet.rules : sheet.cssRules;
    if (rules.length == 0) {
      $('<link rel="stylesheet" type="text/css" href="path/to/local/jquery.mobile-1.0b3.min.css" />').appendTo('head');
    }
 }
})
</script>


답변

질문은 스타일 시트가로드되었는지 여부를 감지하는 것입니다. 한 가지 가능한 접근 방식은 다음과 같습니다.

1) CSS 파일 끝에 다음과 같은 특수 규칙을 추가합니다.

#foo { display: none !important; }

2) HTML에 해당 div를 추가합니다.

<div id="foo"></div>

3) 문서가 준비되면 #foo표시 여부를 확인합니다 . 스타일 시트가로드 된 경우 표시되지 않습니다.

여기 데모 -jquery-ui 부드러움 테마를로드합니다. 스타일 시트에 규칙이 추가되지 않습니다.


답변

css 및 jQuery에 대해 동일한 CDN을 사용한다고 가정하면 한 번의 테스트를 수행하고 모두 잡는 것이 어떻습니까?

<link href="//ajax.googleapis.com/ajax/libs/jqueryui/1/themes/start/jquery-ui.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript">
    if (typeof jQuery == 'undefined') {
        document.write(unescape('%3Clink rel="stylesheet" type="text/css" href="../../Content/jquery-ui-1.8.16.custom.css" /%3E'));
        document.write(unescape('%3Cscript type="text/javascript" src="/jQuery/jquery-1.6.4.min.js" %3E%3C/script%3E'));
        document.write(unescape('%3Cscript type="text/javascript" src="/jQuery/jquery-ui-1.8.16.custom.min.js" %3E%3C/script%3E'));
    }
</script>


답변

이 기사는 부트 스트랩 CSS http://eddmann.com/posts/providing-local-js-and-css-resources-for-cdn-fallbacks/에 대한 몇 가지 솔루션을 제안합니다
.

또는 이것은 fontawesome에서 작동합니다.

<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script>
    (function($){
        var $span = $('<span class="fa" style="display:none"></span>').appendTo('body');
        if ($span.css('fontFamily') !== 'FontAwesome' ) {
            // Fallback Link
            $('head').append('<link href="https://stackoverflow.com/css/font-awesome.min.css" rel="stylesheet">');
        }
        $span.remove();
    })(jQuery);
</script>


답변

에서 스타일 시트가 있는지 테스트 할 수 있습니다document.styleSheets .

var rules = [];
if (document.styleSheets[1].cssRules)
    rules = document.styleSheets[i].cssRules
else if (document.styleSheets[i].rules)
    rule= document.styleSheets[i].rules

사용중인 CSS 파일에 특정한 것을 테스트하십시오.


답변

이를 onerror위해 사용할 수 있습니다 .

<link rel="stylesheet" href="cdn.css" onerror="this.onerror=null;this.href='local.css';" />

그만큼 this.onerror=null; 경우에 자기를 사용할 수없는 대체를 무한 루프를 방지하는 것입니다. 그러나 여러 폴백을 갖는 데 사용될 수도 있습니다.

그러나 이것은 현재 Firefox 및 Chrome에서만 작동합니다.


답변

다음은 katy lavallee의 답변에 대한 확장입니다. 변수 충돌을 방지하기 위해 모든 것을 자체 실행 함수 구문으로 래핑했습니다. 또한 스크립트를 단일 링크에 대해 비 특정 적으로 만들었습니다. IE, 이제 “data-fallback”url 속성이있는 모든 스타일 시트 링크가 자동으로 구문 분석됩니다. 이전과 같이이 스크립트에 URL을 하드 코딩 할 필요가 없습니다. 이는 <head>요소 의 끝이 아닌 끝에서 실행되어야합니다 . <body>그렇지 않으면 FOUC 가 발생할 수 있습니다 .

http://jsfiddle.net/skibulk/jnfgyrLt/

<link rel="stylesheet" type="text/css" href="broken-link.css" data-fallback="broken-link2.css">

.

(function($){
    var links = {};

    $( "link[data-fallback]" ).each( function( index, link ) {
        links[link.href] = link;
    });

    $.each( document.styleSheets, function(index, sheet) {
        if(links[sheet.href]) {
            var rules = sheet.rules ? sheet.rules : sheet.cssRules;
            if (rules.length == 0) {
                link = $(links[sheet.href]);
                link.attr( 'href', link.attr("data-fallback") );
            }
        }
    });
})(jQuery);