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

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

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

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

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

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

我只是不得不写这样的东西,我想分享它。 这个是为多个案件准备的。

  • 如果没有请求的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 } } 

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 } } 

更新 :由于我的答案有几个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 // Eg 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."); } } 

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. } } 

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

与JFK对接受的答案所做的评论一样:

我把这个问题理解为“如何检查一个css文件是否被加载”而不是“如何检查该元素是否存在”。

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

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

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

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/

我的2美分。 这检查是否有任何规则在CSS上设置,这意味着它是否成功加载

 if(jQuery("link[href='/style.css']").prop('sheet').cssRules.length == 0){ //Load the css you want } 

除了上面的所有好的答案,你可以简单地把一个虚拟元素放在你的标记和你的css文件中,给它任何样式,而不是默认的。 然后在代码中检查属性是否应用于哑元素,如果没有,加载CSS。 只是一个想法,而不是一个干净的方式做你想做的事情。

一种方法是:使用document.getElementsByTagName("link")遍历每一个,并检查它的href是否等于你检查的CSS文件。

另一种方法:如果你知道一些CSS规则只在该文件中被设置,检查这个规则是否真的适用,比如检查背景是否真的是红色的。

您可以检查文件名是否在您的标记内,如:

 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 ,如果样式表被加载的话。 这可能会更接近特征检测。

文档对象包含一个包含所有加载样式表的样式表集合。

参考http://www.javascriptkit.com/domref/stylesheet.shtml

你可以循环这个集合来validation你想validation的样式表是否在它里面,然后由浏览器加载。

 document.styleSheets[0] //access the first external style sheet on the page 

有一些浏览器不兼容,但你应该注意。

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

为了获得良好的一致性和可重复的体验,我编写了这两个模仿$.getScript(url, callback) jQuery方法的jQuery插件(但是它们不会像$.getScript()那样强制从服务器重新加载。 :一个可以在任何时候调用CSS文件的加载器,一个只加载一次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"); )} 

callback用法示例:

 $(function() { $.getCachedCssOnce("pathToMyCss/main.css", function() { // Do something once the CSS is loaded });