Как вернуться к локальной таблице стилей (не скрипт) , если CDN не удается
я связываюсь с таблицей стилей jQuery Mobile на CDN и хотел бы вернуться к моей локальной версии таблицы стилей, если 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 терпит неудачу ?
11 ответов:
Не кросс-браузер тестирования, но я думаю, что это будет работать. Однако это должно быть после загрузки 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>
предполагая, что вы используете тот же CDN для CSS и jQuery, почему бы просто не сделать один тест и поймать все это??
<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>
Я думаю, вопрос заключается в том, чтобы определить, загружена ли таблица стилей или нет. Один из возможных подходов заключается в следующем:
1) добавьте специальное правило в конец вашего CSS-файла, например:
#foo { display: none !important; }
2) Добавьте соответствующий div в свой HTML:
<div id="foo"></div>
3) на документ готов, проверить, является ли
#foo
видно или нет. Если таблица стилей была загружена, она не будет видна.демо здесь -- загружает тему гладкости jquery-ui; нет правила добавляется в таблицу стилей.
в этой статье предлагаются некоторые решения для bootstrap 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="/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, который вы используете.
вот расширение к ответу Кэти Лавалли. Я завернул все в самоисполняющийся синтаксис jQuery, чтобы предотвратить столкновения переменных и запустить скрипт на dom ready. Я также сделал скрипт неспецифичным для одной ссылки. Т. е. теперь любая ссылка таблицы стилей с атрибутом url "Data-fallback" будет автоматически проанализирована. Вам не нужно жестко кодировать URL-адреса в этот скрипт, например до.
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);
вы действительно хотите пойти по этому маршруту javascript, чтобы загрузить CSS в случае сбоя CDN?
Я не думал обо всех последствиях для производительности, но вы потеряете контроль над тем, когда CSS загружается, и в целом для производительности загрузки страницы CSS-это первое, что вы хотите загрузить после HTML.
Почему бы не обработать это на уровне инфраструктуры-сопоставьте свое собственное доменное имя с CDN, дайте ему короткий TTL, контролируйте файлы на CDN (например, используя Watchmouse или что-то еще), если CDN не удается, измените DNS на резервный сайт.
другие параметры, которые могут помочь,-это "кэш навсегда" на статическом контенте, но нет никакой гарантии, что браузер сохранит их, конечно, или с помощью app-cache.
на самом деле, как кто-то сказал наверху, если ваш CDN ненадежен, получите новый
Энди
посмотрите на эти функции:
$.ajax({ url:'CSS URL HERE', type:'HEAD', error: function() { AddLocalCss(); }, success: function() { //file exists } });
а вот ванильная версия JavaScript:
function UrlExists(url) { var http = new XMLHttpRequest(); http.open('HEAD', url, false); http.send(); return http.status!=404; } if (!UrlExists('CSS URL HERE') { AddLocalCss(); }
теперь собственно функция:
function AddLocalCss(){ document.write('<link rel="stylesheet" type="text/css" href=" LOCAL CSS URL HERE">') }
просто убедитесь, что AddLocalCss вызывается в голове.
вы также можете рассмотреть возможность использования одного из следующих способов объяснил в этом ответе:
загрузить с помощью AJAX
$.get(myStylesLocation, function(css) { $('<style type="text/css"></style>') .html(css) .appendTo("head"); });
загрузка с помощью динамически созданного
$('<link rel="stylesheet" type="text/css" href="'+myStylesLocation+'" >') .appendTo("head"); Load using dynamically-created <style> $('<style type="text/css"></style>') .html('@import url("' + myStylesLocation + '")') .appendTo("head");
или
$('<style type="text/css">@import url("' + myStylesLocation + '")</style>') .appendTo("head");
можно использовать
onerror
для этого:<link rel="stylesheet" href="cdn.css" onerror="this.onerror=null;this.href='local.css';" />
The
this.onerror=null;
это, чтобы избежать бесконечных петель в случае, если резервный он сам не доступен. Но он также может быть использован для нескольких резервных версий.однако в настоящее время это работает только в Firefox и Chrome.
Я бы, наверное, использовал что-то вроде yepnope.js
yepnope([{ load: 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js', complete: function () { if (!window.jQuery) { yepnope('local/jquery.min.js'); } } }]);
принято от readme.