如何用Javascript创建<style>标签?

309 html javascript css

我正在寻找一种<style>使用JavaScript 将标记插入HTML页面的方法.

到目前为止我找到的最佳方式:

var divNode = document.createElement("div");
divNode.innerHTML = "<br><style>h1 { background: red; }</style>";
document.body.appendChild(divNode);
Run Code Online (Sandbox Code Playgroud)

这适用于Firefox,Opera和Internet Explorer,但不适用于Google Chrome.<br>IE的前端也有点难看.

有谁知道创建<style>标签的方法

  1. 更好

  2. 适用于Chrome?

或者可能

  1. 这是我应该避免的非标准事情

  2. 三个工作浏览器很棒,谁还使用Chrome?

Chr*_*oph 610

尝试将style元素添加到head而不是body.

这在IE(7-9),Firefox,Opera和Chrome中进行了测试:

var css = 'h1 { background: red; }',
    head = document.head || document.getElementsByTagName('head')[0],
    style = document.createElement('style');

head.appendChild(style);

style.type = 'text/css';
if (style.styleSheet){
  // This is required for IE8 and below.
  style.styleSheet.cssText = css;
} else {
  style.appendChild(document.createTextNode(css));
}
Run Code Online (Sandbox Code Playgroud)

  • @RobW - 在IE8及以下版本中不支持.现代浏览器支持它,但不是所有主要浏览器. (28认同)
  • 仅供参考,所有主流浏览器均支持[`document.head`](https://developer.mozilla.org/en/DOM/document.head). (14认同)
  • @allenhwkim:答案早于`querySelector()`的引入; 今天,我可能会选择`document.head`,自IE9起可用 (7认同)
  • 为什么不使用`document.querySelector("head")`?这是IE8支持的事件[来源](https://developer.mozilla.org/en-US/docs/Web/API/document.querySelector) (5认同)
  • 在访问`style.styleSheet.cssText`之前,我必须将style元素附加到头部。在附加之前,`style.styleSheet`为null。 (2认同)

tou*_*ine 61

const style = document.createElement("style")
style.textContent = "h1 { background-color: red; }"
document.head.appendChild(style)
Run Code Online (Sandbox Code Playgroud)

现代而简单的方法

上面的代码是它的要点;如果您想知道原因,请继续阅读。

为什么还有另一个答案?接受的答案是旧的,并且包含针对过时浏览器(例如 Internet Explorer)的冗余代码。其他答案不必要地复杂或使用.innerHTML允许跨站点脚本攻击的属性。

type不需要该属性

大多数答案都type像这样设置属性:style.type = "text/css"。除非您需要支持较旧的浏览器,否则不需要设置此属性。

根据<style>:样式信息元素- HTML | MDN,该type属性是可选的,默认为text/css

type

该属性将样式语言定义为 MIME 类型(不应指定字符集)。text/css该属性是可选的,如果不指定则默认为;text/css不使用除空字符串或以外的值。注意:几乎没有理由在现代 Web 文档中包含此属性。

添加 CSS

要添加 CSS,请使用它.textContent,因为它比其他方法更安全、更快速。相反.innerHTML,它不解析 HTML,因此可以防止跨站点脚本攻击

另一个类似的属性 ,.innerText类似于,.textContent但考虑了 CSS 样式,并且仅表示“渲染的”文本内容。因为我们对仅“渲染”的内容不感兴趣,所以我们更喜欢.textContent

设置有什么.textContent作用?

设置该.textContent属性会删除节点(元素)的所有子节点,并将它们替换为给定的字符串值。

将元素放置在哪里?

样式元素应包含在标题中:“该<style>元素必须包含在<head>文档的内部......”。[ <样式> ... | ]

为了获得 head 的使用,document.head因为它已经被所有主要浏览器支持很长时间了,所以不需要其他后备。

  • 这是最好的答案。2010 年左右的旧答案并没有错,只是已经过时了。感谢您提供最新的答案,并且我很欣赏关于为什么不再需要一些旧的跳跃的解释。 (2认同)

Chr*_*oph 36

这是一个脚本,它将IE风格createStyleSheet()addRule()方法添加到没有它们的浏览器:

if(typeof document.createStyleSheet === 'undefined') {
    document.createStyleSheet = (function() {
        function createStyleSheet(href) {
            if(typeof href !== 'undefined') {
                var element = document.createElement('link');
                element.type = 'text/css';
                element.rel = 'stylesheet';
                element.href = href;
            }
            else {
                var element = document.createElement('style');
                element.type = 'text/css';
            }

            document.getElementsByTagName('head')[0].appendChild(element);
            var sheet = document.styleSheets[document.styleSheets.length - 1];

            if(typeof sheet.addRule === 'undefined')
                sheet.addRule = addRule;

            if(typeof sheet.removeRule === 'undefined')
                sheet.removeRule = sheet.deleteRule;

            return sheet;
        }

        function addRule(selectorText, cssText, index) {
            if(typeof index === 'undefined')
                index = this.cssRules.length;

            this.insertRule(selectorText + ' {' + cssText + '}', index);
        }

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

您可以通过添加外部文件

document.createStyleSheet('foo.css');
Run Code Online (Sandbox Code Playgroud)

并通过动态创建规则

var sheet = document.createStyleSheet();
sheet.addRule('h1', 'background: red;');
Run Code Online (Sandbox Code Playgroud)


Tom*_*Tom 33

我假设您要插入style标记与link标记(引用外部CSS),这就是以下示例所做的:

<html>
 <head>
  <title>Example Page</title>
 </head>
 <body>
  <span>
   This is styled dynamically via JavaScript.
  </span>
 </body>
 <script type="text/javascript">
   var styleNode = document.createElement('style');
   styleNode.type = "text/css";
   // browser detection (based on prototype.js)
   if(!!(window.attachEvent && !window.opera)) {
        styleNode.styleSheet.cssText = 'span { color: rgb(255, 0, 0); }';
   } else {
        var styleText = document.createTextNode('span { color: rgb(255, 0, 0); } ');
        styleNode.appendChild(styleText);
   }
   document.getElementsByTagName('head')[0].appendChild(styleNode);
 </script>
</html>
Run Code Online (Sandbox Code Playgroud)

另外,我在你的问题中注意到你正在使用innerHTML.这实际上是一种将数据插入页面的非标准方式.最佳实践是创建文本节点并将其附加到另一个元素节点.

关于你的最后一个问题,你会听到一些人说你的工作应该适用于所有的浏览器.这一切都取决于你的观众.如果您的观众中没有人使用Chrome,那么请不要冒汗; 但是,如果您希望尽可能覆盖最大的受众群体,那么最好支持所有主要的A级浏览器

  • (很晚的评论)"这一切都取决于你的观众.如果你的观众中没有人使用Chrome,那么就不要冒汗了"这种态度导致人们在IE7甚至IE8之后被锁定在IE6中**可用."但我必须使用的网络应用程序****只适用于IE6" (6认同)
  • 这和我的解决方案基本相同;它们都不能在 IE 中运行! (2认同)
  • 对于 IE,使用“styleNode.styleSheet.cssText = ...” (2认同)
  • 是的,你是对的,我也不一定提倡这样做(因此整体而言:“如果你希望吸引尽可能多的受众,那么最好支持所有主要的 A 级浏览器”),但了解您平台的受众很重要。 (2认同)

bel*_*laz 23

一个有效且符合所有浏览器的示例:

var ss = document.createElement("link");
ss.type = "text/css";
ss.rel = "stylesheet";
ss.href = "style.css";
document.getElementsByTagName("head")[0].appendChild(ss);
Run Code Online (Sandbox Code Playgroud)

  • 错误的元素:`style`没有`rel`或`href`属性 - 你的意思是`link`? (7认同)
  • `link`元素与问题有什么关系?OP要求'style`元素.这个答案与这个问题无关 (3认同)
  • @vsync`style`用于添加内联样式,`link`对于样式表源是正确的,这具有避免跨浏览器问题的优点。 (2认同)

vsy*_*ync 21

对于那些已经使用jQuery的人,你可以使用这个单行程序:

document.head.insertAdjacentHTML("beforeend", `<style>body{background:red}</style>`)
Run Code Online (Sandbox Code Playgroud)

  • 同意,这是最好和简单的,但如果你无法控制它,请注意错误注入的 css! (3认同)
  • 这是最好,最简单的解决方案,谢谢! (2认同)

Gar*_*aro 7

通常需要覆盖现有规则,因此在HEAD中添加新样式并不适用于所有情况.

我想出了这个简单的函数,它总结了所有无效的 "附加到BODY"的方法,并且使用和调试(IE8 +)更方便.

window.injectCSS = (function(doc){
    // wrapper for all injected styles and temp el to create them
    var wrap = doc.createElement('div');
    var temp = doc.createElement('div');
    // rules like "a {color: red}" etc.
    return function (cssRules) {
        // append wrapper to the body on the first call
        if (!wrap.id) {
            wrap.id = 'injected-css';
            wrap.style.display = 'none';
            doc.body.appendChild(wrap);
        }
        // <br> for IE: http://goo.gl/vLY4x7
        temp.innerHTML = '<br><style>'+ cssRules +'</style>';
        wrap.appendChild( temp.children[1] );
    };
})(document);
Run Code Online (Sandbox Code Playgroud)

演示:codepen,jsfiddle


小智 6

document.head.innerHTML += `
  <style>
    h1 {
      color: red; 
    }
    p {
      color: blue;
    }
  </style>`
Run Code Online (Sandbox Code Playgroud)
<h1>I'm red!</h1>
<p>I'm blue!</p>
Run Code Online (Sandbox Code Playgroud)

迄今为止最直接的解决方案。您所要做的就是style在反引号之间键入与通常声明标签相同的内容


小智 5

以下是动态添加类的变体

function setClassStyle(class_name, css) {
  var style_sheet = document.createElement('style');
  if (style_sheet) {
    style_sheet.setAttribute('type', 'text/css');
    var cstr = '.' + class_name + ' {' + css + '}';
    var rules = document.createTextNode(cstr);
    if(style_sheet.styleSheet){// IE
      style_sheet.styleSheet.cssText = rules.nodeValue;
    } else {
      style_sheet.appendChild(rules);
    }
    var head = document.getElementsByTagName('head')[0];
    if (head) {
      head.appendChild(style_sheet);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

一切都很好,但是要让 styleNode.cssText 在 IE6 中使用 javascipt 创建的节点工作,您需要在设置 cssText 之前将该节点附加到文档;

更多信息@http ://msdn.microsoft.com/en-us/library/ms533698%28VS.85%29.aspx


Spo*_*oky 5

该对象变量会将style标签附加到具有type属性和一个简单转换规则的head标签上,该规则与每个id / class / element匹配。可以随意修改content属性并根据需要注入任意数量的规则。只要确保内容中的CSS规则保持一行即可(或者,如果愿意,可以“转义”每一行)。

var script = {

  type: 'text/css', style: document.createElement('style'), 
  content: "* { transition: all 220ms cubic-bezier(0.390, 0.575, 0.565, 1.000); }",
  append: function() {

    this.style.type = this.type;
    this.style.appendChild(document.createTextNode(this.content));
    document.head.appendChild(this.style);

}}; script.append();
Run Code Online (Sandbox Code Playgroud)


7vu*_*0hy 5

你写了:

var divNode = document.createElement("div");
divNode.innerHTML = "<br><style>h1 { background: red; }</style>";
document.body.appendChild(divNode);
Run Code Online (Sandbox Code Playgroud)

为什么不是这个?

var styleNode = document.createElement("style");
document.head.appendChild(styleNode);
Run Code Online (Sandbox Code Playgroud)

从此以后,您可以轻松地将 CSS 规则附加到 HTML 代码中:

styleNode.innerHTML = "h1 { background: red; }\n";
styleNode.innerHTML += "h2 { background: green; }\n";
Run Code Online (Sandbox Code Playgroud)

...或者直接到 DOM:

styleNode.sheet.insertRule("h1 { background: red; }");
styleNode.sheet.insertRule("h2 { background: green; }");
Run Code Online (Sandbox Code Playgroud)

我希望除了过时的浏览器之外,它可以在任何地方工作。

绝对可以在2019 年的Chrome 中使用。