COME verificare se un file CSS esterno (tra domini) viene caricato utilizzando Javascript

Ho una funzione che effettua la seguente utilizzando javascript :

  1. Crea un elemento di collegamento e imposta href = cssFile.
  2. Inserisci l’elemento link nel tag head.
  3. Crea un elemento div.
  4. Imposta il nome della class usando setAttribute
  5. appendChild il div sul corpo.
  6. Ora document.defaultView.getComputedStyle(divElement, null)[cssRule] valore della regola CSS usando document.defaultView.getComputedStyle(divElement, null)[cssRule] .

Ora getComputedStyle sta restituendo i valori predefiniti, e se aspetto il breakpoint usando Firebug prima getComputedStyle chiamata getComputedStyle , restituisce la regola CSS dal CSS iniettato.

Saluti,
Munim

È ansible creare l’url css dinamico e recuperare il css come testo normale utilizzando una normale chiamata ajax.

Quindi usalo per caricare il css:

 function loadCss(cssText, callback){ var style = document.createElement('style'); style.type='text/css'; if(callBack != undefined){ style.onload = function(){ callBack(); }; } style.innerHTML = cssText; head.appendChild(style); } 

E usalo in questo modo:

 loadCss(ajaxResponseText, function(){ console.log("yaay css loaded, now i can access css defs"); }) 

Questo è in realtà quello che ho fatto.

Per garantire che venga caricato un file CSS specifico, ho aggiunto uno stile alla fine del file CSS. Per esempio:

 #ensure-cssload-8473649 { display: none } 

Ora ho una funzione JavaScript che triggers la richiamata specificata quando lo stile sopra è caricato nella pagina:

 var onCssLoad = function (options, callback) { var body = $("body"); var div = document.createElement(constants.TAG_DIV); for (var key in options) { if (options.hasOwnProperty(key)) { if (key.toLowerCase() === "css") { continue; } div[key] = options[key]; } } var css = options.css; if (css) { body.appendChild(div); var handle = -1; handle = window.setInterval(function () { var match = true; for (var key in css) { if (css.hasOwnProperty(key)) { match = match && utils.getStyle(div, key) === css[key]; } } if (match === true) { window.clearTimeout(handle); body.removeChild(div); callback(); } }, 100); } } 

Ed è così che ho usato la funzione sopra:

 onCssLoad({ "id": "ensure-cssload-8473649", css: { display: "none" } }, function () { // code when you want to execute // after your CSS file is loaded }); 

Qui il 1 ° parametro prende le options cui id deve controllare lo stile di test e la proprietà css da verificare rispetto a ciò che viene caricato dal CSS.

Presumo che tu stia facendo questo perché devi creare dynamicmente l’URL del foglio di stile.

Le opzioni di coppia vengono in mente:

1) Creare l’URL lato server ed evitare del tutto questo problema.

2) Utilizzare un setTimeout per verificare se lo stile è stato caricato e controllare ogni 20ms circa fino a quando getComputedStyle restituisce il valore desiderato.

Il # 2 non mi piace per niente … ma è un’opzione. Se si utilizza # 2, assicurarsi di cancellare il timeout anche se c’è un’eccezione.

Ecco una soluzione che sembra funzionare su tutti i browser.

 function loadCss(fileUrl) { // check for css file type if (fileUrl.indexOf(".css")==fileUrl.length-4) { // Create link element var fileref=document.createElement("link"); fileref.setAttribute("rel", "stylesheet"); fileref.setAttribute("type", "text/css"); fileref.setAttribute("href", fileUrl); if (typeof fileref!="undefined") { // remove the . if this is a relative link if(fileUrl.indexOf('.')==0) { fileUrl = fileUrl.substr(1); } // generate the full URL to use as the fileId var pathname = window.location.pathname; var pathUrl = pathname.substr(0,pathname.lastIndexOf("/")); var fileId = window.location.protocol + "//" + window.location.host + pathUrl + fileUrl; // append the newly created link tag to the head of the document document.getElementsByTagName("head")[0].appendChild(fileref); // begin checking for completion (100ms intervals up to 2000ms) this.checkCSSLoaded(fileId,100,0,2000); } else throw 'INVALID_CSS_ERROR'; } else throw 'INVALID_CSS_ERROR'; } function checkCSSLoaded(cssHref,milliPerCheck,milliPerCount,milliTimeout) { // Look through all sheets and try to find the cssHref var atSheet = -1; var sheetLength = document.styleSheets.length; while(++atSheet < sheetLength ) { if(cssHref == document.styleSheets[atSheet].href) { // If found dispatch and event or call a procedure /* Do whatever is next in your code here */ return; } } // check for timeout if(milliCount > milliTimeout) { alert('INVALID_CSS_ERROR::'+" ("+cssHref+"+ not found!"); /* Do whatever happens if timeout is reached here */ return; } // else keep trying setTimeout(checkCSSLoaded ,milliPerCheck, cssHref, milliPerCheck, milliCount+millPerCheck, milliTimeout); } 

Essenzialmente noi

  1. Crea un tag link.
  2. Imposta i suoi attributi in modo che conosca un tag link del foglio di stile
  3. Crea un ID file in modo tale che sia sempre l’URL del file completo
  4. Aggiungi il tag link alla testata del documento
  5. Esegui test consecutivi per vedere se (stylesheet.href == fileID) esiste
    • Se trovato fai qualcos’altro se il timeout fa qualcos’altro continua a controllare

Usare document.styleSheets per verificare se un css è caricato è sbagliato, poiché non appena un link css viene aggiunto al DOM, sarà disponibile da document.styleSheets, anche se non è ancora stato caricato.

Anche l’aggiunta di un marker ai CSS è hacky.

La soluzione corretta è ascoltare l’evento onload:

  var loadedCss = {}; cssHref = "http://www.foo.com/bar.css"; css = document.createElement("link"); css.setAttribute("rel", "stylesheet"); css.setAttribute("type", "text/css"); css.setAttribute("href", cssHref); css.onload = function(){ loadedCss[cssHref] = true; } document.getElementsByTagName("head")[0].appendChild(css); function isCssLoaded(url) { return loadCss[url]; }