我需要检查(在 Javascript 中)是否加载了 CSS 文件,如果没有则加载它。jQuery 很好。
如果未加载,如何使用 Javascript 检查和加载 CSS?
IT技术
javascript
jquery
css
2021-03-13 15:57:43
6个回答
只需检查是否<link>
存在href
属性设置为 CSS 文件 URL的元素:
if (!$("link[href='/path/to.css']").length)
$('<link href="/path/to.css" rel="stylesheet">').appendTo("head");
简单的 ol' 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
}
}
更新:由于我的回答得到了一些赞成,这促使我修改了代码,因此我决定对其进行更新。
// 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.");
}
}
TL; 博士
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 文件是否已加载”而不是“如何检查元素是否存在”。
该元素可能存在(路径也可能正确),但这并不意味着 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;}
Java脚本
//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/
除了上面所有不错的答案之外,您还可以简单地在标记中和 css 文件中放置一个虚拟元素,为其指定除默认值以外的任何样式。然后在代码中检查该属性是否应用于虚拟元素,如果没有,则加载css。只是一个想法,而不是做你想做的事情的巧妙方法。