2013-06-29 14 views
5

Sto utilizzando un CDN per caricare Bootstrap.css. La mia domanda è come posso controllare se il bootstrap CDN è stato caricato/trovato. E se non lo fosse, quindi caricare Boostrap locale.Modernizr Yepnope Css Fallback

Ecco Jquery ripiego ..

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

E questo è come mi caricare Modernizr di 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> 

Non ho idea di come ho potuto verificare se il CSS è stato caricato .. proprio come ho fatto con Modernizr e jQuery ..

Grazie in anticipo ...

risposta

1

Stoyan Stefanov has had a Pure JS solution for this for some time now, che in realtà ha appena ricevuto un aggiornamento non molto tempo fa. Controlla il link per una scomposizione approfondita.

Ma style.sheet.cssRules verrà popolato solo una volta che il file è stato caricato, quindi verificandolo ripetutamente con un setInterval che si è in grado di rilevare una volta caricato il file 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 riconosce l'uso di questa tecnica, anche se si nota nella loro documentazione di YepNope "callback non aspetta il css effettivamente essere caricato".

In aggiunta al recente deprezzamento di YepNope, passiamo a una soluzione che si integra con Modernizr (che non includerà più YepNope nel loro software), ma non utilizza alcuna delle librerie di Modernizr, poiché non hanno ancora un nativo soluzione. Offirmo combina un paio di tecniche pulite da Robert Nyman e Abdul Munim per consentire a Modernizr di sapere che il CSS è effettivamente caricato.

Si comincia con la seguente funzione, che ci permette di ottenere la proprietà CSS di un elemento:

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

Poi usiamo il seguente funtion per creare un elemento DOM nascosto per testare le proprietà CSS entro:

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); 
    } 
} 

Ora siamo in grado di conoscere in modo affidabile, all'interno Modernizr, se il nostro CSS è pronto a partire:

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!') 
       } 
      } 
     } 
    } 
]); 
+0

Una nota per testare questo: il CDN è molto veloce, e quel file è minimizzato, quindi carica molto velocemente. JSFiddle e CodePen mostra "caricato!" subito. Otterrai risultati migliori creando ed eseguendo un file HTML locale. – Madness

+0

Questa è un'ottima risposta. È solo che usa un controllo personalizzato, quindi in questo senso si potrebbe anche usare un framework come [fallback.io] (http://fallback.io/). Ma dato che la risposta afferma chiaramente che non esiste una soluzione nativa con Modernizr, immagino che sia degna della taglia? – Izhaki

+0

Sì, ho cercato di rimanere il più fedele possibile alla domanda originale, ma un sacco è cambiato dal 2013. Il grande YepNope una volta è ammortizzato. Modernizr sta rilasciando la prossima versione di conseguenza. Modernizr non ha ancora una soluzione nativa. Quindi sono partito dal presupposto che l'OP avrebbe comunque voluto utilizzare Modernizr, quindi sono andato con la soluzione di usare i controlli JS puri piuttosto che nella direzione di un'altra libreria. Ma io, per certo, non posso decidere se meritare la generosità, che è la comunità a decidere :) – Madness