Мне нужно проверить (в Javascript), если загружен файл CSS, а если нет, то загрузить его. jQuery в порядке.
Как использовать Javascript для проверки и загрузки CSS, если он не загружен?
Ответ 1
Просто проверьте, существует ли элемент <link>
с атрибутом href
, установленным на ваш URL-адрес файла CSS:
if (!$("link[href='/path/to.css']").length)
$('<link href="/path/to.css" rel="stylesheet">').appendTo("head");
Простой простой метод JS также прост, используя document.styleSheets collection:
function loadCSSIfNotAlreadyLoadedForSomeReason () {
var ss = document.styleSheets;
for (var i = 0, max = ss.length; i < max; i++) {
if (ss[i].href == "/path/to.css")
return;
}
var link = document.createElement("link");
link.rel = "stylesheet";
link.href = "/path/to.css";
document.getElementsByTagName("head")[0].appendChild(link);
}
loadCSSIfNotAlreadyLoadedForSomeReason();
Ответ 2
Мне просто пришлось написать что-то подобное, и я хотел поделиться им. Это готово для нескольких случаев.
- Если запрос для файла css отсутствует (файл css не связан...)
- Если есть запрос для файла css, но если он не сработал (файл css больше не доступен...)
var styles = document.styleSheets;
for (var i = 0; i < styles.length; i++) {
// checking if there is a request for template.css
if (styles[i].href.match("template")) {
console.log("(Iteration: " + i + ") Request for template.css is found.");
// checking if the request is not successful
// when it is successful .cssRules property is set to null
if (styles[i].cssRules != null && styles[i].cssRules.length == 0) {
console.log("(Iteration: " + i + ") Request for template.css failed.");
// fallback, make your modification
// since the request failed, we don't need to iterate through other stylesheets
break;
} else {
console.log("(Iteration: " + i + ") Request for template.css is successful.");
// template.css is loaded successfully, we don't need to iterate through other stylesheets
break;
}
}
// if there isn't a request, we fallback
// but we need to fallback when the iteration is done
// because we don't want to apply the fallback each iteration
// it not like our css file is the first css to be loaded
else if (i == styles.length-1) {
console.log("(Iteration: " + i + ") There is no request for template.css.");
// fallback, make your modification
}
}
TL; версия DR
var styles = document.styleSheets;
for (var i = 0; i < styles.length; i++) {
if (styles[i].href.match("css-file-name-here")) {
if (styles[i].cssRules != null && styles[i].cssRules.length == 0) {
// request for css file failed, make modification
break;
}
} else if (i == styles.length-1) {
// there is no request for the css file, make modification
}
}
Обновить. Поскольку мой ответ получил несколько оборотов, и это привело меня к пересмотру кода, я решил его обновить.
// document.styleSheets holds the style sheets from LINK and STYLE elements
for (var i = 0; i < document.styleSheets.length; i++) {
// Checking if there is a request for the css file
// We iterate the style sheets with href attribute that are created from LINK elements
// STYLE elements don't have href attribute, so we ignore them
// We also check if the href contains the css file name
if (document.styleSheets[i].href && document.styleSheets[i].href.match("/template.css")) {
console.log("There is a request for the css file.");
// Checking if the request is unsuccessful
// There is a request for the css file, but is it loaded?
// If it is, the length of styleSheets.cssRules should be greater than 0
// styleSheets.cssRules contains all of the rules in the css file
// E.g. b { color: red; } that a rule
if (document.styleSheets[i].cssRules.length == 0) {
// There is no rule in styleSheets.cssRules, this suggests two things
// Either the browser couldn't load the css file, that the request failed
// or the css file is empty. Browser might have loaded the css file,
// but if it empty, .cssRules will be empty. I couldn't find a way to
// detect if the request for the css file failed or if the css file is empty
console.log("Request for the css file failed.");
// There is a request for the css file, but it failed. Fallback
// We don't need to check other sheets, so we break;
break;
} else {
// If styleSheets.cssRules.length is not 0 (>0), this means
// rules from css file is loaded and the request is successful
console.log("Request for the css file is successful.");
break;
}
}
// If there isn't a request for the css file, we fallback
// But only when the iteration is done
// Because we don't want to apply the fallback at each iteration
else if (i == document.styleSheets.length - 1) {
// Fallback
console.log("There is no request for the css file.");
}
}
TL; DR
for (var i = 0; i < document.styleSheets.length; i++) {
if (document.styleSheets[i].href && document.styleSheets[i].href.match("/template.css")) {
if (document.styleSheets[i].cssRules.length == 0) {
// Fallback. There is a request for the css file, but it failed.
break;
}
} else if (i == document.styleSheets.length - 1) {
// Fallback. There is no request for the css file.
}
}
Ответ 3
Подходите к комментарию, сделанному JFK о принятом ответе:
Я понял вопрос как "как проверить, является ли файл css загружен или нет", а не "как проверить, является ли элемент существует".
Элемент может существовать (и путь может быть правильным), но он не означает, что файл css был успешно загружен.
Если вы получаете доступ к элементу ссылки через getElementById
, вы не сможете проверить/прочитать стиль, определенный внутри файла CSS.
Чтобы проверить, был ли стиль загружен успешно, мы должны использовать getComputedStyle
(или currentStyle
для IE).
HTML
//somewhere in your html document
<div id="css_anchor"></div>
CSS
//somewhere in your main stylesheet
#css_anchor{display:none;}
JAVASCRIPT
//js function to check the computed value of a style element
function get_computed_style(id, name){
var element = document.getElementById(id);
return element.currentStyle ? element.currentStyle[name] : window.getComputedStyle ? window.getComputedStyle(element, null).getPropertyValue(name) : null;
}
//on document ready check if #css_anchor has been loaded
$(document).ready( function() {
if(get_computed_style('css_anchor', 'display')!='none'){
//if #css_anchor style doesn't exist append an alternate stylesheet
var alternateCssUrl = 'http://example.com/my_alternate_stylesheet.css';
var stylesheet = document.createElement('link');
stylesheet.href = alternateCssUrl;
stylesheet.rel = 'stylesheet';
stylesheet.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(stylesheet);
}
});
Часть ответа поступает из: myDiv.style.display возвращает пустое значение, если установлено в таблице стилей мастера
Демо здесь: http://jsfiddle.net/R9F7R/
Ответ 4
Что-то вроде этого будет делать (используя jQuery):
function checkStyleSheet(url){
var found = false;
for(var i = 0; i < document.styleSheets.length; i++){
if(document.styleSheets[i].href==url){
found=true;
break;
}
}
if(!found){
$('head').append(
$('<link rel="stylesheet" type="text/css" href="' + url + '" />')
);
}
}
Ответ 5
Мои 2 цента. Это проверяет, есть ли какие-либо правила, установленные на css или нет, что означает, что оно было или не было успешно загружено
if(jQuery("link[href='/style.css']").prop('sheet').cssRules.length == 0){
//Load the css you want
}
Ответ 6
Помимо всех хороших ответов выше, вы можете просто поместить фиктивный элемент внутри вашей разметки и в свой файл css, придать ему любой стиль, отличный от значения по умолчанию. Затем в коде проверьте, применяется ли атрибут к фиктивному элементу, а если нет, загрузите css. Просто мысль, но не аккуратный способ сделать то, что вы хотите сделать.
Ответ 7
Один из способов: используйте document.getElementsByTagName("link")
итерацию по каждому из них и проверьте, равен ли его href
файл CSS, который вы проверяете.
Другой способ: если вы знаете, что правило CSS установлено только в этом файле, проверьте, действительно ли это правило применяется, например. проверьте, действительно ли фон чего-то действительно красный.
Ответ 8
var links = document.getElementsByTagName('link');
var file = 'my/file.css';
var found = false;
for ( var i in links )
{
if ( links[i].type == 'text/css' && file == links[i].href ) {
found = true; break;
}
}
if ( !( found ) ) {
var styles = document.getElementsByTagName('style');
var regexp = new RegExp('/\@import url\("?' + file + '"?\);/');
for ( var i in styles )
{
if ( styles[i].src == file ) {
found = true; break;
} else if ( styles[i].innerHTML.match(regexp) ) {
found = true; break;
}
}
}
if ( !( found ) ) {
var elm = document.createElement('link');
elm.href = file;
document.documentElement.appendChild(elm);
}
Ответ 9
Вы можете проверить, находится ли имя файла в вашей разметке, например:
var lnks = document.getElementsByTagName('link'),
loadcss = true;
for(var link in lnks) {
href = link.getAttribute('href');
if( href.indexOf('foooobar.css') > -1) ){
loadcss = false;
return false;
}
});
if( loadcss ) {
var lnk = document.createElement('link'),
head = document.getElementsByTagName('head')[0] || document.documentElement;
lnk.rel = 'stylesheet';
lnk.type = 'text/css';
lnk.href = '//' + location.host + 'foooobar.css';
head.insertBefore(lnk, head.firstChild);
}
или вы можете проверить конкретный className
, который должен быть доступен, если была загружена таблица стилей. Вероятно, это немного ближе к обнаружению функции.
Ответ 10
Объект document содержит коллекцию таблиц стилей со всеми загруженными таблицами стилей.
Для справки см. http://www.javascriptkit.com/domref/stylesheet.shtml
Вы можете зацикливать эту коллекцию, чтобы убедиться, что таблица стилей, которую вы хотите проверить, находится в ней и, таким образом, загружена браузером.
document.styleSheets[0] //access the first external style sheet on the page
Есть некоторые несовместимости браузеров, которые вам следует искать.
Ответ 11
Для приятного последовательного и повторяемого опыта я написал эти два плагина jQuery, которые имитируют метод $.getScript(url, callback)
jQuery (однако они НЕ будут принудительно перезагружать сервер с помощью $.getScript()
. Есть два метода: один, который будет загружайте файл CSS в любое время, когда он вызывается, и тот, который будет загружать его только один раз. Я нахожу, что он был пригоден во время разработки, когда я вношу изменения, а последний отлично подходит для быстрого развертывания.
/**
* An AJAX method to asynchronously load a CACHED CSS resource
* Note: This removes the jQuery default behaviour of forcing a refresh by means
* of appending a datestamp to the request URL. Actual caching WILL be subject to
* server/browser policies
*/
$.getCachedCss = function getCachedCss(url, callback)
{
$('<link>',{rel:'stylesheet', type:'text/css', 'href':url, media:'screen'}).appendTo('head');
if (typeof callback == 'function')
callback();
}
/**
* An AJAX method to asynchronously load a CACHED CSS resource Only ONCE.
* Note: This removes the jQuery default behaviour of forcing a refresh by means
* of appending a datestamp to the request URL. Actual caching WILL be subject to
* server/browser policies
*/
$.getCachedCssOnce = function getCachedCssOnce(url, callback)
{
if (!$("link[href='" + url + "']").length) {
$.getCachedCss(url, callback);
if (typeof callback == 'function')
callback();
}
}
Пример использования:
$(function() {
$.getCachedCssOnce("pathToMyCss/main.css");
)}
Пример использования с обратным вызовом:
$(function() {
$.getCachedCssOnce("pathToMyCss/main.css", function() {
// Do something once the CSS is loaded
});
Ответ 12
используйте .sheet в jQuery:
HTML:
<link rel="stylesheet" href="custom.css">
JQuery
if($("link[href='custom.css']")[0].sheet.cssRules.length==0){
//custom.css was not loaded, do your backup loading here
}
Ответ 13
простой способ с помощью JavaScript..,
loadCssIfNotLoaded('https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css');
loadCssIfNotLoaded('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css');
function loadCssIfNotLoaded(url) {
var element=document.querySelectorAll('link[href="' + url + '"]');
if (element.length == 0)
{
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
}
}
Ответ 14
В одну строку с помощью jQuery. Если #witness div видим, мы должны загрузить файл css.
В HTML у нас есть:
<div id="witness"></div>
В загружаемом файле CSS мы имеем:
#witness{display:none;}
Таким образом, если файл CSS загружен, div #witness не отображается. Мы можем проверить с JQuery и принять решение.
!$('#witness').is(':visible') || loadCss() ;
Как фрагмент:
function loadCss(){
//...
console.log('Css file required');
};
!$('#witness').is(':visible') || loadCss();
#witness{display:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="witness"></div>