Есть ли способ определить, когда файл CSS был полностью загружен? - PullRequest
31 голосов
/ 20 декабря 2010

Я тестировал множество ленивых загрузчиков для JavaScript и CSS, которые вставляют теги и для загрузки файлов.Однако проблема в том, что теги <link> не запускаются onload, поэтому их трудно определить, когда они загружены.Единственный обходной путь, который я нашел для этого, состоит в том, чтобы установить display: none; (в файле CSS, который должен быть загружен) для фиктивного элемента и опросить этот элемент, чтобы проверить, когда он был установлен для отображения: нет.Но это, помимо того, что уродливо, конечно, работает только для одного файла CSS.

Так что мне было интересно;Есть ли другой способ определить, был ли загружен файл CSS?

Ответы [ 9 ]

16 голосов
/ 23 декабря 2010

edit: Следует отметить, что поддержка браузером событий загрузки для файлов CSS улучшилась со времени моего первоначального ответа. Хотя это не полностью поддерживается, поэтому мой ответ ниже по-прежнему имеет некоторое значение. Вот таблица совместимости , хотя и не уверен, насколько достоверен источник.

Хорошо, я наконец нашел решение.

Этот парень http://tugll.tugraz.at/96784/weblog/9080.html вставляет теги ссылки и опрашивает document.styleSheets [index] .rules, пока он больше не будет неопределенным (где index, конечно, является индексом вновь вставленного файла). К сожалению, его код содержит ошибки и работает только с Safari & FF. Поэтому я исправил ошибки, добавил функциональность для Opera и Internet Explorer и даже добавил функции для добавления нескольких файлов CSS и JS и 1 финальный обратный вызов (когда все файлы загружены) в простой и удобной функции lazyloader. Результат можно найти здесь:

https://github.com/LukasBombach/Lazyloader

3 голосов
/ 20 декабря 2010

Попробуйте добавить определенное правило CSS в конец файла и подождите, пока не будет применен CSS (проверьте это с помощью JavaScript).После этого вы можете быть уверены, что CSS был загружен.Однако у меня нет опыта с этим.Возможно, стоит попробовать небольшую идею.

3 голосов
/ 20 декабря 2010

Редактировать: (из-за возможной не поддержки WebKit)

Так что я бы лучше порекомендовал JQuery LOADER

$("a.button, input.button, button.button").Loader(
{
    url: [
        'core.css',
        'theme.css',
        'button.css'
    ],
    success: function() {
        $(this).button();
    }
});

Вы можете взглянуть на LazyLoad Библиотека JavaScript.

LazyLoad является крошечным (всего 1541 байт), без зависимостей Библиотека JavaScript, которая делает это супер легко загрузить внешний JavaScript и (новое в этой версии) CSS файлы на потребность. Идеально подходит для быстрого и ненавязчивая загрузка большого внешнего скрипты и таблицы стилей либо лениво после того, как остальная часть страницы закончил погрузку или по требованию как необходимо.

В дополнение к поддержке CSS, эта версия LazyLoad также добавляет поддержку для параллельной загрузки нескольких ресурсы в браузерах, которые его поддерживают. Чтобы загрузить несколько ресурсов в параллельно, просто передать массив URL в одном звонке LazyLoad

2 голосов
/ 01 октября 2015

Стоит знать, что сейчас текущие версии Chrome и Firefox запускают событие onload по ссылкам.

var cssFile = document.createElement("link");
cssFile.setAttribute("rel", "stylesheet");
cssFile.setAttribute("type", "text/css");
// Add event listener
cssFile.onload = function(){ console.log('loaded'); }
cssFile.setAttribute("href", 'pathToYour.css');
document.getElementsByTagName("head")[0].appendChild(cssFile);
2 голосов
/ 23 мая 2014

Я хотел дать некоторое представление о том, что могло измениться.

Согласно одному из последних параграфов документации Mozilla <link>, событие загрузки может быть присоединено к элементу ссылки в версиях FF 9и выше, а также Chrome 19 и выше.IE и Safari не указаны.https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link

1 голос
/ 16 ноября 2017

попробуйте это: 1 - предварительная загрузка css на голове

<link rel="preload" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" as="style" onload="this.rel='stylesheet'"> 
<link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'"> 

2 - предварительная загрузка js-файла в нижний колонтитул

    <link rel="preload" as="script" href="https://ajax.googleapis.com/ajax/libs/jquery/2.2.1/jquery.min.js">
    <link rel="preload" as="script" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
    <link rel="preload" as="script" href="script.js">

3 - перед тегом </body> добавление

<script>        
/**  load defer css - js*/  
// defer css
var cssAll = document.querySelectorAll('[as="style"]');
for(i = 0; i < cssAll.length; i++){
    if(cssAll[i].getAttribute("rel") == "preload"){         
        cssAll[i].setAttribute("rel", "stylesheet");
    }
}
//defer js
var jsAll = document.querySelectorAll('[as="script"]');
if(!window.jQuery)
{
    // load jquery lib
    var script = document.createElement('script');
    script.type = "text/javascript";
    script.src = jsAll[0].getAttribute("href");
    document.getElementsByTagName('head')[0].appendChild(script);
   // load other lib after load jquery
    script.onload = function () {
        for(i = 1; i < jsAll.length; i++){
            var jsNext = document.createElement('script');
            jsNext.type = "text/javascript";
            jsNext.src = jsAll[i].getAttribute("href");
            document.getElementsByTagName('head')[0].appendChild(jsNext);
        }
    }   
}
</script>   

Я тестировал на Firefox 57, Chrome 61, Yandex, не тестировал на Opera и т. Е.

1 голос
/ 20 декабря 2010

О «правилах CSS для проверки загрузки»:

Если в своем JS-скрипте вы добавляете в голову тег стиля, содержащий простое правило, например: #loadingCss {display: block;}

Тогда вам просто нужно добавить во все ваши CSS-файлы что-то вроде: #loadingCss {display: none;}

В заголовке документа вы добавляете тег стиля перед тегом ссылки.Таким образом, правило CSS в файле CSS будет более важным (тот же селектор -> тот же приоритет, последний в документе - победитель).

Чем в вашем JS-скрипте вам просто нужно проверить#loadingCss видимость.Как только вы узнаете, что ваш CSS-файл загружен, вы можете удалить тег стиля.

Для следующего CSS-файла, который вы хотите загрузить, вы можете снова добавить этот тег стиля в конце элемента head.

Таким образом, используя только одно правило, вы можете управлять загрузкой всех ваших CSS-файлов.Единственная проблема с этим решением: вы не можете загружать более одного файла CSS одновременно.Но я уверен, что можно найти способ сделать это.

Но в любом случае, я не уверен, что это решение (использующее правило CSS для проверки загрузки) является очень хорошим решением.Может быть, есть другие способы сделать это.

1 голос
/ 20 декабря 2010

При использовании загрузчика скриптов, например Supply, это будет выглядеть так:

supply.listen('text/css', function(payload, filename) {
    switch(filename) {
        case: 'foo.css': {
            // do something
            break;
        }
        case: 'baseball.css': {
            break;
        }
        // ...
    }
});

supply.files({
    stylesheet: [
        'foo.css',
        'baseball.css'
    ]
});

Ссылка: SupplyJS

0 голосов
/ 30 июля 2018

На сегодняшний день это самое простое и лучшее решение, которое я нашел, и оно отлично работает:

var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = css_url;

head.appendChild(link);

var img = document.createElement('img');
document.body.appendChild(img);

img.onerror = img.onload = function() {
    img.onerror = img.onload = null;
    document.body.removeChild(img);
    // do whatever you need to do when css loaded;
};

img.src = css_url;
...