Como determinar se o CSS foi carregado?

Como posso afirmar que o CSS de uma página carregou e aplicou com sucesso seus estilos no Watin 2.1?

Depois de fazer algumas pesquisas e escrever minha resposta, me deparei com esse link que explica tudo o que você precisa saber sobre CSS, quando ele é carregado e como você pode verificar isso.

O link fornecido explica isso tão bem, na verdade, que estou adicionando algumas citações para referência futura.
Se você está curioso, minha resposta seria # 2 e uma variação de # 4.

Quando é que uma folha de estilo é realmente carregada?

Com isso fora do caminho, vamos ver o que temos aqui.

// my callback function // which relies on CSS being loaded function CSSDone() { alert('zOMG, CSS is done'); }; // load me some stylesheet var url = "http://tools.w3clubs.com/pagr/1.sleep-1.css", head = document.getElementsByTagName('head')[0], link = document.createElement('link'); link.type = "text/css"; link.rel = "stylesheet"; link.href = url; // MAGIC // call CSSDone() when CSS arrives head.appendChild(link); 

Opções para a parte mágica, classificadas de agradável e fácil a ridícula

  1. listen to link.onload
  2. ouça o link.addEventListener (‘load’)
  3. ouvir link.onreadystatechange
  4. setTimeout e verifique se há mudanças em document.styleSheets
  5. setTimeout e verifique se há mudanças no estilo de um elemento específico que você cria, mas estilo com o novo CSS

A quinta opção é muito louca e assume que você tem controle sobre o conteúdo do CSS, então esqueça. Além disso, ele verifica os estilos atuais em um tempo limite, o que significa que irá liberar a fila de restream e pode ser potencialmente lento. Quanto mais lento o CSS chegar, mais reflui. Então, esqueça isso.

Então, que tal implementar a magia?

 // MAGIC // #1 link.onload = function () { CSSDone('onload listener'); }; // #2 if (link.addEventListener) { link.addEventListener('load', function() { CSSDone("DOM's load event"); }, false); }; // #3 link.onreadystatechange = function() { var state = link.readyState; if (state === 'loaded' || state === 'complete') { link.onreadystatechange = null; CSSDone("onreadystatechange"); } }; // #4 var cssnum = document.styleSheets.length; var ti = setInterval(function() { if (document.styleSheets.length > cssnum) { // needs more work when you load a bunch of CSS files quickly // eg loop from cssnum to the new length, looking // for the document.styleSheets[n].href === url // ... // FF changes the length prematurely :( CSSDone('listening to styleSheets.length change'); clearInterval(ti); } }, 10); // MAGIC ends 

Houve uma atualização no artigo alinhado por @ShadowScripter. O novo método supostamente funciona em todos os navegadores, incluindo o FF.

 var style = document.createElement('style'); style.textContent = '@import "' + url + '"'; var fi = setInterval(function() { try { style.sheet.cssRules; // <--- MAGIC: only populated when file is loaded CSSDone('listening to @import-ed cssRules'); clearInterval(fi); } catch (e){} }, 10); document.getElementsByTagName('head')[0].appendChild(style); 

Depois de carregar a página, você pode verificar o estilo em alguns dos seus elementos algo como isto:

 var style = browser.Div(Find.ByClass("class")).Style; Assert.That(Style.Display, Is.StringContaining("none")); Assert.That(Style.FontSize, Is.EqualTo("10px")); 

E etc …

Como a compatibilidade do navegador pode variar e os novos padrões futuros do navegador estão sujeitos a alterações, eu recomendaria uma combinação do ouvinte onload e adicionar CSS à folha de estilo para que você possa ouvir quando o z-index dos elementos HTML for alterado se você estiver usando um único folha de estilos. Caso contrário, use a function abaixo com uma nova meta tag para cada estilo.

Adicione o seguinte ao arquivo CSS que você está carregando:

 #*(insert a unique id for he current link tag)* { z-index: 0 } 

Adicione o seguinte ao seu script:

 function whencsslinkloads(csslink, whenload ){ var intervalID = setInterval( function(){ if (getComputedStyle(csslink).zIndex !== '0') return; clearInterval(intervalID); csslink.onload = null; whenload(); }, 125 // check for if it has loaded 8 times a second ); csslink.onload = function(){ clearInterval(intervalID); csslink.onload = null; whenload(); } } 

Exemplo

index.html :

        CSS Loaded: no   

script.js :

 function whencsslinkloads(csslink, whenload ){ var intervalID = setInterval( function(){ if (getComputedStyle(csslink).zIndex !== '0') return; clearInterval(intervalID); csslink.onload = null; whenload(); }, 125 // check for if it has loaded 8 times a second ); csslink.onload = function(){ clearInterval(intervalID); csslink.onload = null; whenload(); } } /*************************************/ whencsslinkloads( document.getElementById('EpicStyleID'), function(){ document.getElementById('result').innerHTML = '' } ) 

the_style.css

 #EpicStyleID { z-index: 0 } 

POR FAVOR, não faça seu script carregar de forma síncrona (sem o atributo async ) apenas para capturar o evento onload do link. Existem maneiras melhores, como o método acima.