【问题标题】:Add CSS to <head> with JavaScript?使用 JavaScript 将 CSS 添加到 <head>?
【发布时间】:2010-10-13 09:03:01
【问题描述】:

有没有办法将 javascript 文件中的字符串中的 css 添加到带有 javascript 的文档的头部?

假设我们有一个网页,它有一个灯箱脚本,这个脚本需要一个 css 文件才能运行。

现在使用&lt;link&gt; 添加这个 css 文件将使 css 文件即使对于没有启用 js 的人也能下载。

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

所以我在想,如果你可以将你在 css 文件中的 css 放入脚本中,让脚本解析 css 并将其添加到头部,或者更好的是让脚本添加css 直接进入文档的&lt;head&gt;

但是我在网上没有找到任何暗示这是可能的,那么是否可以用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);
 }

【问题讨论】:

标签: javascript html css


【解决方案1】:

编辑:正如 Atspulgs 评论所建议的,您可以在不使用 jQuery 的情况下使用 querySelector

document.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" />');

你可以找到这个问题的完整教程here

【讨论】:

  • 同样,这个方法会加载一个新文件,这是 Yuri 想要避免的。此外,为这样简单的事情加载整个 jQuery 库是相当愚蠢的。
  • 没有 jQuery: document.querySelector('head').innerHTML += '';
  • document.head,是head 元素!
【解决方案2】:

当您尝试使用 JavaScript 将 CSS 字符串添加到 &lt;head&gt; 时? 将 CSS 字符串注入到页面中,使用 &lt;link&gt; 元素比使用 &lt;style&gt; 元素更容易。

下面将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" />

您可以通过对 CSS 字符串进行 URL 编码并将其添加到 HREF 属性来在 JavaScript 中创建它。比所有 &lt;style&gt; 元素的怪癖或直接访问样式表要简单得多。

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 操作,并且只需要一个元素。

【讨论】:

  • let linkElement: HTMLLinkElement = this.document.createElement('link'); 可以在 IE 5.5 中运行,你说?
  • @JānisElmeris 如果您使用 ie 所使用的语法的 javascript,它会。 createElement 和 setAttribute 不是新方法。
  • @BogdanM.,好吧,我只是希望描述为“这将在......中工作”的代码实际上已经具有正确的语法。
  • let linkElement: HTMLLinkElement = ... - 这个语法叫什么?
  • 抱歉,这是 Typescript 类型。它不应该在那里。
【解决方案3】:

如果不想依赖javascript库,可以使用document.write()吐出需要的css,用style标签包裹,直接进入文档head

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

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

已经建议/添加/删除了其他解决方案,但我认为将已经可以跨浏览器运行良好的东西过度复杂化并没有任何意义。祝你好运!

http://jsbin.com/oqede3/edit

【讨论】:

  • 这很好,直到您想在文档呈现后添加 CSS 规则。
  • 好在 OP 没有那个要求!您的解决方案涵盖了这一点,但恕我直言,对于非 js/lightbox css 降级来说,这完全是矫枉过正。
  • 需要注意的一点:document.write 在真正的 XHTML 文档中不起作用,但这不太可能成为问题,因为几乎没有人真正使用 XHTML。
  • 有趣的是它可以工作,但在正文中具有风格看起来有点 hacky :) p.s.您可以将 document.write 放在网站的 head 部分,它似乎工作正常。
  • 我会尽量避免 document.write。
【解决方案4】:

一个简单的非 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 或在 style 元素上使用 appendChild。这是一个bug report,它证明了这一点,尽管我认为它错误地识别了问题。上面的解决方法来自错误报告中的 cmets,并且已经在 IE6 和 IE9 中进行了测试。

你是使用这个,document.write还是更复杂的解决方案,真的取决于你的情况。

【讨论】:

  • 在 IE 中不起作用。当然不是 6 或 7,现在没有 8 可用于测试。 IE 不喜欢document.createElement('style')
  • @Tim 在 IE6 和 9 中为我工作,因为您的解决方案具有完全相同的行,也许您可​​以进一步解释
  • @roryf:哦,是的,你是对的,对不起。愚蠢的是,我犯了一个基本错误,即相信 IE 错误中的行号。错误实际上在styleElement.innerHTML = css; 中。在 IE 7 中肯定会失败,现在在 IE 6 中重新测试(等待 VM 启动)。
  • @Tim 谢谢,我怀疑这可能是个问题,因为我没有正确测试而感到羞耻!
  • 我不能不管这个,所以做了一些研究,找到了 IE 的解决方法,现在应该可以跨浏览器了
【解决方案5】:

这是一个在所有主流浏览器中动态创建 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样式表转成这个会很费劲。
【解决方案6】:

这是一个简单的方法。

/**
 * Add css to the document
 * @param {string} css
 */
function addCssToDocument(css){
  var style = document.createElement('style')
  style.innerText = css
  document.head.appendChild(style)
}

【讨论】:

    【解决方案7】:

    一次通话:

    document.head.appendChild(Object.assign(document.createElement("style"), {textContent: `
        select, button, input, details, summary { cursor: pointer }
        input { padding: 0.5rem }
        button, select  { margin: 0.5rem }
        @media (max-width:640px) { button  { width: 100% } i {display: block } }
      `
    }))
    

    【讨论】:

      【解决方案8】:

      最短的一条线

      const addCSS = css => document.head.appendChild(document.createElement("style")).innerHTML = css;
      
      // Usage:
      addCSS("body{background:red}");
      

      【讨论】:

      • 是否可以跨浏览器使用?
      • 应该支持除老IE以外的所有浏览器。如果有人能说出支持的最旧 IE 版本,我将不胜感激。
      【解决方案9】:

      晚会,与所有解决方案非常相似,但仅将脚本附加到head

      export const injectHeadCss = () => {
        let style: HTMLStyleElement | null = document.head.querySelector('style[my-style]');
      
        if (style !== null) {
          return;
        }
      
        style = document.createElement('style');
        style.setAttribute('my-style', '');
        style.innerHTML = `
          .class1 {
            background: pink;
          }
      
          .class2 {
            background: purple;
          }
        `;
      
        document.head.append(style);
      };
      
      

      【讨论】:

        【解决方案10】:

        最大限度地提高兼容性,适用于 2009-2022 年甚至更久的大多数产品。这个解决方案是故意不使用 ES6 等的;使用箭头函数、let-variable、a​​ppend (2014) 等。

        这个简短的版本为网页的 head-section 添加了样式,也可以通过 DOM 访问 head-section 以进一步最大化兼容性 - 因为 querySelector 直到 2009 年才被广泛采用。

        请注意,现在不建议将 innerHTML / write 用于生产。

        只需将其复制并粘贴到控制台中即可试用,这样的页面会得到一些不错的补充;

        function ahsf(styling){ document.querySelector('head').innerHTML+="<style>"+ styling +"</style>";}
        //Called with
        ahsf(" * { border: 1px dashed #f09 !important; } ");
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-11
          • 2013-04-22
          • 2016-05-22
          • 2012-08-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多