Подтвердить что ты не робот

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

Мне нужно проверить (в Javascript), если загружен файл CSS, а если нет, то загрузить его. jQuery в порядке.

4b9b3361

Ответ 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>