web-dev-qa-db-fra.com

Comment déterminer si CSS a été chargé?

Comment puis-je affirmer que le CSS d'une page a correctement chargé et appliqué ses styles dans Watin 2.1?

19
Erik Funkenbusch

Après avoir fait quelques recherches et rédigé ma réponse, je suis tombé sur ce lien qui explique tout ce que vous devez savoir sur le CSS, son chargement et la manière de le vérifier. 

Le lien fourni explique si bien, en fait, que j’en ajoute quelques citations pour référence future.
Si vous êtes curieux, ma réponse serait n ° 2 et une variante de n ° 4.

Quand une feuille de style est-elle vraiment chargée?

...  

Ceci étant dit, voyons ce que nous avons ici.

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

Options pour la partie magique, classées de Nice-et-facile à ridicules

  1. écoutez link.onload
  2. écoutez link.addEventListener ('load')
  3. écoutez link.onreadystatechange
  4. setTimeout et vérifiez les modifications dans document.styleSheets
  5. setTimeout et vérifie les changements de style d'un élément spécifique que vous créez, mais style avec le nouveau CSS

5ème option est trop fou et suppose que vous avez le contrôle sur le contenu du CSS, alors oubliez-le. De plus, il vérifie les styles en cours dans un délai d'attente, ce qui signifie qu'il videra la file d'attente de redistribution et peut être potentiellement lent. Plus la CSS est lente à arriver, plus il y a de reflux. Alors, vraiment, oublie ça.

Alors, qu'en est-il de la magie?

// 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
        // e.g. 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
25
ShadowScripter

L'article mis à jour par @ShadowScripter a été mis à jour. La nouvelle méthode est censée fonctionner dans tous les navigateurs, y compris 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);
7
JohnSz

Après le chargement de la page, vous pouvez vérifier le style de certains de vos éléments:

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

Et etc...

2
alonp

Étant donné que la compatibilité des navigateurs peut varier et que les nouvelles normes de navigation futures sont susceptibles de changer, il est recommandé d'associer l'écouteur onload à l'ajout de CSS à la feuille de style afin que vous puissiez écouter le moment où l'index z des éléments HTML change si vous utilisez un seul feuille de style. Sinon, utilisez la fonction ci-dessous avec une nouvelle balise Meta pour chaque style.

Ajoutez ce qui suit au fichier CSS que vous chargez:

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

Ajoutez les éléments suivants à votre 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();
    }
}

Exemple

index.html:

<!doctype html>
<html>
    <head>
        <link rel=stylesheet id="EpicStyleID" href="the_style.css" />
        <script async href="script.js"></script>
    </head>
    <body>
        CSS Loaded: <span id=result>no</span>
    </body>
</html>

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 = '<font color=green></font>'
    }
)

the_style.css

#EpicStyleID {
    z-index: 0
}

VEUILLEZ ne pas charger votre script de manière synchrone (sans l'attribut async) afin que vous puissiez capturer l'événement onload du lien. Il existe de meilleurs moyens, comme la méthode ci-dessus.

0
Jack Giffin