Есть ли способ обнаружить, когда файл CSS был полностью загружен?
Я тестировал много ленивых загрузчиков для JavaScript и CSS, которые вставляют <script> и <link> теги для загрузки файлов. Однако проблема в том, что теги <link>
не запускают onload
, поэтому их трудно обнаружить, когда они загружены. Единственное обходное решение, которое я нашел для этого, - установить display: none;
(в файле CSS, который должен быть загружен) на фиктивный элемент, и опросить этот элемент, чтобы проверить, когда он был установлен для отображения: none. Но это, помимо уродства, конечно, работает только для одного файла CSS.
Так что мне было интересно; Есть ли другой способ определить, загружен ли файл CSS?
Ответы
Ответ 1
Изменить: Следует отметить, что поддержка браузера для событий onload в файлах CSS улучшилась с момента моего первоначального ответа. Тем не менее, это не полностью поддерживается, поэтому мой ответ ниже по-прежнему имеет некоторое значение. Вот диаграмма совместимости, но не уверен, насколько закончен источник.
Хорошо, я наконец нашел решение.
Этот парень http://tugll.tugraz.at/96784/weblog/9080.html вставляет ссылки-теги и опросы document.styleSheets [index].rules, пока он больше не будет неопределенным (где индекс, конечно, является индексом нового вставленный файл). К сожалению, его код глючит и работает только с Safari & FF. Поэтому я исправил ошибки, добавил функциональность для Opera и Internet Explorer и даже добавил функции для добавления нескольких файлов CSS и JS и 1 окончательного обратного вызова (когда все файлы загружены) в сладкой и простой функции lazyloader. Результат можно найти здесь:
https://github.com/LukasBombach/Lazyloader
Ответ 2
Изменить: (из-за возможного отсутствия поддержки WebKit)
Поэтому я бы предпочел рекомендовать JQuery LOADER
$("a.button, input.button, button.button").Loader(
{
url: [
'core.css',
'theme.css',
'button.css'
],
success: function() {
$(this).button();
}
});
Вы можете посмотреть LazyLoad библиотеку JavaScript.
LazyLoad - это крошечный (только 1,541 байт), без зависимости Библиотека JavaScript, которая делает его супер легко загрузить внешний JavaScript и (новый в этой версии) CSS файлы на спрос. Идеально подходит для быстрого и ненавязчивая загрузка больших внешних скрипты и таблицы стилей лениво после того, как остальная часть страницы готовая загрузка или по требованию, как необходимо.
В дополнение к поддержке CSS эта версия LazyLoad также добавляет поддержку для параллельной загрузки нескольких ресурсов в браузерах, которые его поддерживают. Чтобы загрузить несколько ресурсов в параллельно, просто передайте массив URL-адресов в одном LazyLoad cal
Ответ 3
Попробуйте добавить определенное правило CSS в конец вашего файла и дождаться применения CSS (проверьте это с помощью JavaScript). После этого вы можете быть уверены, что CSS загружен. Однако у меня нет опыта в этом. Просто быстрая идея, возможно, стоит попробовать.
Ответ 4
Я хотел бы дать некоторое представление о том, что могло измениться.
В соответствии с одним из последних абзацев документации Mozilla <link>
событие загрузки может быть присоединено к элементу ссылки в версиях FF 9 и выше, а также к Chrome 19 и выше. IE и Safari не указаны. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
Ответ 5
Полезно знать, что сейчас текущие версии 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);
Ответ 6
Используя загрузчик script, например 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'
]
});
Ref.: SupplyJS
Ответ 7
Об "правилах CSS проверки загрузки":
Если в вашем JS script вы добавили в свою голову тег стиля, содержащий простое правило: #loadingCss {display: block; }
Чем вам просто нужно добавить во все ваши файлы CSS что-то вроде: #loadingCss {display: none; }
В заголовке вашего документа вы добавляете тег стиля перед тегом ссылки. Таким образом, правило CSS в файле CSS будет более важным (тот же самый селектор → тот же приоритет, последний в документе - победитель).
Чем в JS script вам просто нужно проверить видимость #loadingCss.
Как только вы узнаете, что ваш файл CSS загружен, вы можете удалить тег стиля.
Для следующего файла CSS, который вы хотите загрузить, вы можете добавить этот тег стиля еще раз в конце элемента head.
Таким образом, только с одним правилом вы можете управлять загрузкой всех ваших файлов CSS.
Единственная проблема с этим решением: вы не можете загружать более одного файла CSS за раз. Но я уверен, что можно найти способ сделать это.
Но в любом случае я не уверен, что это решение (с использованием правила CSS для проверки загрузки) - очень хорошее решение. Возможно, есть и другие способы сделать это.
Ответ 8
попробуйте следующее:
1- preload 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, не тестировался в опере и т.е.
Ответ 9
Это, безусловно, самое простое и лучшее решение, которое я нашел до сих пор, и он отлично работает:
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;