jquery - temas - Cómo retroceder a la hoja de estilo local(no a la secuencia de comandos) si la CDN falla
jquery official (10)
¿De verdad quieres ir por esta ruta javascript para cargar CSS en caso de que falle un CDN?
No he pensado en todas las implicaciones de rendimiento, pero perderá el control de cuándo se carga el CSS y, en general, del rendimiento de la carga de la página, CSS es lo primero que desea descargar después del HTML.
¿Por qué no manejar esto en el nivel de infraestructura? Mapea tu propio nombre de dominio a la CDN, dale un TTL corto, monitorea los archivos en la CDN (por ejemplo, usando Watchmouse u otra cosa), si CDN falla, cambia el DNS al sitio de respaldo.
Otras opciones que pueden ser útiles son "caché para siempre" en contenido estático, pero no hay garantía de que el navegador las mantenga por supuesto o utilizando la aplicación-caché.
En realidad, como alguien dijo en la parte superior, si su CDN no es confiable, obtenga uno nuevo
Andy
Me estoy vinculando a la hoja de estilo jQuery Mobile en un CDN y me gustaría volver a mi versión local de la hoja de estilos si falla el CDN. Para los scripts, la solución es bien conocida:
<!-- 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>
Me gustaría hacer algo similar para una hoja de estilo:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css" />
No estoy seguro si se puede lograr un enfoque similar porque no estoy seguro de si el navegador bloquea de la misma manera al vincular un script que cuando carga un script (quizás sea posible cargar una hoja de estilo en una etiqueta de script y luego inyectarlo en la página)?
Entonces mi pregunta es: ¿cómo me aseguro de que una hoja de estilo se cargue localmente si falla un CDN?
Aquí hay una extensión de la respuesta de katy lavallee. Envolví todo en sintaxis de jQuery autoejecutable para evitar colisiones variables y ejecutar el script en Dom Ready. También hice que el script no sea específico para un solo enlace. IE, ahora cualquier enlace de hoja de estilo con un atributo url "data-fallback" se analizará automáticamente. No es necesario codificar las URL en este script como antes.
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);
Es posible que pueda probar la existencia de la hoja de estilo en 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
Pruebe algo específico del archivo CSS que está utilizando.
Mira estas funciones:
$.ajax({
url:''CSS URL HERE'',
type:''HEAD'',
error: function()
{
AddLocalCss();
},
success: function()
{
//file exists
}
});
Y aquí está la versión de JavaScript vanilla:
function UrlExists(url)
{
var http = new XMLHttpRequest();
http.open(''HEAD'', url, false);
http.send();
return http.status!=404;
}
if (!UrlExists(''CSS URL HERE'') {
AddLocalCss();
}
Ahora la función real:
function AddLocalCss(){
document.write(''<link rel="stylesheet" type="text/css" href=" LOCAL CSS URL HERE">'')
}
Solo asegúrese de llamar a AddLocalCss en la cabeza.
También podría considerar usar una de las siguientes formas explicadas en esta respuesta :
Cargar usando AJAX
$.get(myStylesLocation, function(css)
{
$(''<style type="text/css"></style>'')
.html(css)
.appendTo("head");
});
Cargar usando dinámicamente creado
$(''<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");
o
$(''<style type="text/css">@import url("'' + myStylesLocation + ''")</style>'')
.appendTo("head");
No probado en varios navegadores, pero creo que funcionará. Sin embargo, tendrá que ser posterior a la carga de jquery, o tendrá que volver a escribirlo en 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>
Probablemente usaría algo como 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'');
}
}
}]);
Tomado del léame.
Supongo que la pregunta es detectar si una hoja de estilo está cargada o no. Un posible enfoque es el siguiente:
1) Agregue una regla especial al final de su archivo CSS, como:
#foo { display: none !important; }
2) Agregue el div correspondiente en su HTML:
<div id="foo"></div>
3) En el documento listo, verifique si #foo
es visible o no. Si la hoja de estilo fue cargada, no será visible.
Demostración aquí : carga el tema de suavidad de jquery-ui; ninguna regla se agrega a la hoja de estilo.
Suponiendo que está utilizando el mismo CDN para css y jQuery, ¿por qué no hacer una prueba y capturarlo todo?
<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>
este artículo sugiere algunas soluciones para bootstrap css http://eddmann.com/posts/providing-local-js-and-css-resources-for-cdn-fallbacks/
alternativamente, esto funciona para 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>
//(load your cdn lib here first)
<script>window.jQuery || document.write("<script src=''//me.com/path/jquery-1.x.min.js''>/x3C/script>")</script>