Как определить, загружен ли CSS?

Как я могу подтвердить, что CSS для страницы успешно загружен и применил свои стили в Watin 2.1?


person Erik Funkenbusch    schedule 10.05.2012    source источник
comment
Попробуйте создать событие http://stackoverflow.com/questions/2571164/jquery-event-that-triggers-after-css-is-loaded   -  person yAnTar    schedule 10.05.2012
comment
@yAnTar - я не уверен, как это помогает ... Мне не нужна куча кода ajax на моих страницах, который используется только для тестирования.   -  person Erik Funkenbusch    schedule 10.05.2012


Ответы (4)


Проведя небольшое исследование и написав свой ответ, я наткнулся на эту ссылку, которая объясняет все, что вам нужно знать о CSS, когда он загружен и как вы можете это проверить.

Приведенная ссылка объясняет это настолько хорошо, что я добавляю несколько цитат для использования в будущем.
Если вам интересно, мой ответ будет №2 и вариант №4 .

Когда действительно загружается таблица стилей?

...

Разобравшись с этим, давайте посмотрим, что у нас здесь.

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

Варианты волшебной части, отсортированные от простого к смешному

  1. слушать link.onload
  2. слушать link.addEventListener ('load')
  3. слушать ссылку. onreadystatechange
  4. setTimeout и проверьте наличие изменений в document.styleSheets
  5. setTimeout и проверьте наличие изменений в стиле определенного элемента, который вы создаете, но с новым CSS.

Пятый вариант слишком безумный и предполагает, что вы контролируете содержимое CSS, так что забудьте об этом. Кроме того, он проверяет текущие стили по таймауту, что означает, что он очистит очередь перекомпоновки и может быть потенциально медленным. Чем медленнее приходит CSS, тем больше перекомпоновок. Так что забудь об этом.

Так как насчет применения магии?

// 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
person ShadowScripter    schedule 14.05.2012
comment
Проверьте мой ответ, который относится к важному последующему обновлению статьи, на которую ссылается @ShowScripter. - person JohnSz; 16.01.2014

Произошло обновление статьи, опубликованной @ShadowScripter. Предположительно новый метод работает во всех браузерах, включая 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);
person JohnSz    schedule 15.01.2014

После загрузки страницы вы можете проверить стиль некоторых элементов примерно так:

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

И так далее...

person alonp    schedule 14.05.2012
comment
Хорошо, но это только часть проблемы. Это только подтверждает, что стиль применен, а не то, что все стили правильно загружены. Например, как я могу убедиться, что заданное фоновое изображение загружается как часть стиля? При проверке стиля будет указано, что у стиля есть фоновое изображение, но как я могу убедиться, что это изображение загружено и отображается? - person Erik Funkenbusch; 14.05.2012
comment
Вы можете проверить свойства элемента и т.д ... тест на видимость можно проводить только на глаз. если у вас есть решение для этого, буду рад узнать ответ :) - person alonp; 14.05.2012

Поскольку совместимость с браузером может различаться, а новые будущие стандарты браузера могут быть изменены, я бы рекомендовал комбинацию прослушивателя onload и добавления CSS в таблицу стилей, чтобы вы могли отслеживать изменения z-index элементов HTML, если вы используете один таблица стилей. В противном случае используйте функцию ниже с новым метатегом для каждого стиля.

Добавьте в загружаемый файл CSS следующее:

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

Добавьте в свой скрипт следующее:

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

Пример

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
}

ПОЖАЛУЙСТА, не заставляйте ваш скрипт загружаться синхронно (без атрибута async), чтобы вы могли зафиксировать событие onload ссылки. Есть способы получше, например, описанный выше.

person Jack Giffin    schedule 08.08.2017