使用JavaScript将CSS添加到<head>?


71

有没有一种方法可以将javascript文件中的字符串中的css添加到使用javascript的文档的开头?

假设我们有一个网页,其中包含一个灯箱脚本,该脚本需要一个css文件才能运行。

现在,添加此css文件<link>将使css文件下载,即使对于未启用js的用户也是如此。

我知道我可以使用脚本动态加载css文件,但这也意味着将有2个http请求,并且在文件中几乎没有css的情况下,我发现这种效率低下。

所以我对自己想,如果您可以将css文件中的css放入脚本中,让该脚本解析css并将其添加到头部,或者更好的是让脚本直接将css添加到脚本中的 <head>该文件中。

但是我没有在网上发现任何暗示这是可行的方法,因此是否有可能用js将css添加到头部?

编辑+解决方案:

我将roryf的答案编辑为可跨浏览器使用(IE5除外)

Javascript:

 function addcss(css){
    var head = document.getElementsByTagName('head')[0];
    var s = document.createElement('style');
    s.setAttribute('type', 'text/css');
    if (s.styleSheet) {   // IE
        s.styleSheet.cssText = css;
    } else {                // the world
        s.appendChild(document.createTextNode(css));
    }
    head.appendChild(s);
 }

1
看看下面的链接..它解释了有关您的问题的每一个小细节...并且它用Javascript
Gabriele Petrioli 2010年

Answers:


26

当您尝试<head>使用JavaScript向其中添加CSS字符串时?将CSS字符串注入页面中,使用<link>元素比使用<style>元素更容易做到这一点。

以下将p { color: green; }规则添加到页面。

<link rel="stylesheet" type="text/css" href="data:text/css;charset=UTF-8,p%20%7B%20color%3A%20green%3B%20%7D" />

您只需在URL中对CSS字符串进行编码并将其添加为HREF属性,就可以在JavaScript中创建它。比所有<style>元素或直接访问样式表的古怪要简单得多。

var linkElement = this.document.createElement('link');
linkElement.setAttribute('rel', 'stylesheet');
linkElement.setAttribute('type', 'text/css');
linkElement.setAttribute('href', 'data:text/css;charset=UTF-8,' + encodeURIComponent(myStringOfstyles));

这将在IE 5.5以上版本中运行

您标记的解决方案可以使用,但是此解决方案需要较少的dom操作,并且只需要一个元素。


1
let linkElement: HTMLLinkElement = this.document.createElement('link');你说可以在IE 5.5中使用吗?
贾尼斯·埃默里斯(JānisElmeris)'18年

@JānisElmeris,如果您将javascript与ie所使用的语法一起使用。createElement和setAttribute不是新方法。
Bogdan M.

@BogdanM。,嗯,我只是希望描述为“这将在...中工作”的代码实际上已经具有正确的语法。
贾尼斯·埃默里斯(JānisElmeris)

let linkElement: HTMLLinkElement = ...-这个语法叫什么?
Scott Martin

抱歉,这是Typescript类型。它不应该真的在那里。
moefinley

31

编辑:正如Atspulgs的注释所建议的,您可以使用querySelector在不使用jQuery的情况下实现相同效果:

document.querySelector('head').innerHTML += '<link rel="stylesheet" href="styles.css" type="text/css"/>';

下面是较旧的答案。


您可以使用jQuery库来选择您的head元素并将HTML附加到其上,如下所示:

$('head').append('<link rel="stylesheet" href="style2.css" type="text/css" />');

您可以在这里找到有关此问题的完整教程


4
同样,此方法将加载一个新文件,Yuri希望避免这种情况。而且,以这样简单的方式加载整个jQuery库是相当愚蠢的。
TRiG 2010年

4
没有jQuery:document.querySelector('head')。innerHTML + ='<link rel =“ stylesheet” href =“ styles.css” type =“ text / css” />';;
Atspulgs

3
document.head,是head元素!
Iharob Al Asimi

26

如果您不想依赖Javascript库,则可以使用document.write()吐出包装在style标记中的所需CSS ,直接插入文档中head

<head>
  <script type="text/javascript">
    document.write("<style>body { background-color:#000 }</style>");
  </script>
  # other stuff..
</head>

这样,您可以避免触发额外的HTTP请求。

还建议/添加/删除了其他解决方案,但我认为在使跨浏览器正常运行的功能变得过于复杂方面没有任何意义。祝好运!

http://jsbin.com/oqede3/edit


13
很好,除非您要在呈现文档后添加CSS规则。
Tim Down

好东西OP没有那个要求!您的解决方案涵盖了这一点,但是恕我直言,对于这样的非js / lightbox css降级,这完全是多余的。
杰里科

2
需要注意的一件事:document.write在真正的XHTML文档中不起作用,但这不太可能成为问题,因为几乎没有人真正使用XHTML。
Tim Down

有趣的是,它可以工作,但是在主体中具有样式似乎有点古怪:) ps可以将document.write放在站点的头部,并且看起来工作正常。
Timo Huovinen 2010年

1
我会尽可能避免document.write。
Orcra 2014年

14

一个简单的非jQuery解决方案,尽管对于IE来说有一点漏洞:

var css = ".lightbox { width: 400px; height: 400px; border: 1px solid #333}";

var htmlDiv = document.createElement('div');
htmlDiv.innerHTML = '<p>foo</p><style>' + css + '</style>';
document.getElementsByTagName('head')[0].appendChild(htmlDiv.childNodes[1]);

看来IE不允许设置innerTextinnerHTML或使用appendChildstyle的元素。这是一个错误报告尽管我认为它错误地识别了问题,但是证明了这一点。以上解决方法来自错误报告中的注释,并已在IE6和IE9中进行了测试。

是否使用它,document.write还是更复杂的解决方案将取决于您的情况。


在IE中不起作用。当然不是6或7,现在没有可供测试的8。IE不喜欢document.createElement('style')
Tim Down

@Tim在IE6和9中为我工作,因为您的解决方案具有完全相同的
说法,

@roryf:哦,是的,你是对的,对不起。我愚蠢地犯了一个基本错误,就是相信IE错误中的行号。错误实际上在中styleElement.innerHTML = css;。在IE 7中肯定会失败,现在在IE 6中重新测试(等待VM生效)。
Tim Down

@蒂姆,谢谢,我怀疑这可能是一个问题,对我的测试不当感到羞耻!
roryf

2
我不能离开这个,所以做了一些研究,找到了IE的解决方法,现在应该可以跨浏览器使用了
roryf

9

这是一个将在所有主要浏览器中动态创建CSS规则的函数。 createCssRule接受一个选择器(例如“ p.purpleText”),一个规则(例如“ color:purple;”)和一个可选的Document(默认情况下使用当前文档):

var addRule;

if (typeof document.styleSheets != "undefined" && document.styleSheets) {
    addRule = function(selector, rule) {
        var styleSheets = document.styleSheets, styleSheet;
        if (styleSheets && styleSheets.length) {
            styleSheet = styleSheets[styleSheets.length - 1];
            if (styleSheet.addRule) {
                styleSheet.addRule(selector, rule)
            } else if (typeof styleSheet.cssText == "string") {
                styleSheet.cssText = selector + " {" + rule + "}";
            } else if (styleSheet.insertRule && styleSheet.cssRules) {
                styleSheet.insertRule(selector + " {" + rule + "}", styleSheet.cssRules.length);
            }
        }
    }
} else {
    addRule = function(selector, rule, el, doc) {
        el.appendChild(doc.createTextNode(selector + " {" + rule + "}"));
    };
}

function createCssRule(selector, rule, doc) {
    doc = doc || document;
    var head = doc.getElementsByTagName("head")[0];
    if (head && addRule) {
        var styleEl = doc.createElement("style");
        styleEl.type = "text/css";
        styleEl.media = "screen";
        head.appendChild(styleEl);
        addRule(selector, rule, styleEl, doc);
        styleEl = null;
    }
};

createCssRule("body", "background-color: purple;");

非常详尽的答案,我相信它会派上用场,但是采用简单的CSS样式表并将其转换为该样式表将非常麻烦。
Timo Huovinen

5

这是一个简单的方法。

/**
 * Add css to the document
 * @param {string} css
 */
function addCssToDocument(css){
  var style = document.createElement('style')
  style.innerText = css
  document.head.appendChild(style)
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.