如果没有加载,如何使用Javascript检查和加载CSS?

Sal*_*ake 56 javascript css jquery

我需要检查(在Javascript中)是否加载了CSS文件,如果没有,则加载它.jQuery很好.

And*_*y E 86

只需检查一个<link>元素是否存在,并将href属性设置为CSS文件的URL:

if (!$("link[href='/path/to.css']").length)
    $('<link href="/path/to.css" rel="stylesheet">').appendTo("head");
Run Code Online (Sandbox Code Playgroud)

使用document.styleSheets集合,简单的'JS方法也很简单:

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();
Run Code Online (Sandbox Code Playgroud)

  • 我将问题理解为"如何检查是否加载了css文件"而不是"如何检查`<link>`元素是否存在".`<link>`元素可能存在(并且路径也可能是正确的),但这并不意味着css文件已成功加载.所以,重新措辞问题:如果没有加载css文件(例如与cdn服务器的通信问题),如何加载(本地)css(回退)文件呢? (40认同)
  • 这不是这个问题的答案. (14认同)
  • `document.styleSheets` 是如何跨浏览器的? (2认同)

aki*_*uri 14

我只是写了类似的东西,我想分享它.这个是为多个案件准备的.

  • 如果没有请求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's 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:由于我的回答有一些upvotes,这导致我修改代码,我决定更新它.

// 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's 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's 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.");
    }
}
Run Code Online (Sandbox Code Playgroud)

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.
    }
}
Run Code Online (Sandbox Code Playgroud)


Raf*_*shi 7

同意JFK关于接受答案的评论:

我将问题理解为"如何检查是否加载了css文件",而不是"如何检查元素是否存在".

元素可能存在(并且路径也可能是正确的),但这并不意味着css文件已成功加载.

如果您通过链接元素访问,则 getElementById无法检查/读取CSS文件中定义的样式.

为了检查样式是否已成功加载,我们必须使用getComputedStyle(或currentStyle用于IE).

HTML

//somewhere in your html document

<div id="css_anchor"></div>
Run Code Online (Sandbox Code Playgroud)

CSS

//somewhere in your main stylesheet

#css_anchor{display:none;}
Run Code Online (Sandbox Code Playgroud)

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

            }
    });
Run Code Online (Sandbox Code Playgroud)

部分答案来自:myDiv.style.display在主样式表中设置时返回空白

演示:http://jsfiddle.net/R9F7R/


Sea*_*oyd 5

这样的事情会做(使用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 + '" />')
       );
   }
}
Run Code Online (Sandbox Code Playgroud)