Как создать тег <style>с помощью Javascript? - PullRequest
294 голосов
/ 08 февраля 2009

Я ищу способ вставить тег <style> в HTML-страницу с помощью JavaScript.

Лучший способ, который я нашел до сих пор:

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

Это работает в Firefox, Opera и Internet Explorer, но не в Google Chrome. Также немного уродливо с <br> впереди для IE.

Кто-нибудь знает способ создания тега <style>, который

  1. приятнее

  2. Работает с Chrome?

Или, может быть

  1. Это нестандартная вещь, которую мне следует избегать

  2. Три рабочих браузера великолепны, а кто вообще использует Chrome?

Ответы [ 13 ]

580 голосов
/ 08 февраля 2009

Попробуйте добавить элемент 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));
}
33 голосов
/ 08 февраля 2009

Вот скрипт, который добавляет методы IE 100 * 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;
    })();
}

Вы можете добавить внешние файлы через

document.createStyleSheet('foo.css');

и динамически создавать правила с помощью

var sheet = document.createStyleSheet();
sheet.addRule('h1', 'background: red;');
31 голосов
/ 08 февраля 2009

Я предполагаю, что вы хотите вставить тег 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>

Также я заметил в вашем вопросе, что вы используете innerHTML. На самом деле это нестандартный способ вставки данных на страницу. Рекомендуется создать текстовый узел и добавить его к другому узлу элемента.

Что касается вашего последнего вопроса, вы услышите, как некоторые люди говорят, что ваша работа должна работать во всех браузерах. Все зависит от вашей аудитории. Если никто из вашей аудитории не использует Chrome, не переживайте; однако, если вы хотите охватить как можно большую аудиторию, лучше всего поддерживать все основные браузеры класса А

22 голосов
/ 08 февраля 2009

Пример, который работает и совместим со всеми браузерами:

var ss = document.createElement("link");
ss.type = "text/css";
ss.rel = "stylesheet";
ss.href = "style.css";
document.getElementsByTagName("head")[0].appendChild(ss);
16 голосов
/ 22 февраля 2015

Для тех, кто уже использует jQuery , вы можете использовать этот однострочный:

$('<style>'+ styles +'</style>').appendTo(document.head);
7 голосов
/ 07 октября 2014

Часто возникает необходимость переопределить существующие правила, поэтому добавление новых стилей в HEAD работает не во всех случаях.

Я придумал эту простую функцию, которая суммирует все недопустимо подходы "присоединить к телу" и просто удобнее использовать и отлаживать (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);

Демонстрация: codepen , jsfiddle

5 голосов
/ 18 декабря 2009

Вот вариант для динамического добавления класса

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);
    }
  }
}
4 голосов
/ 16 февраля 2015

Эта переменная объекта добавит тег стиля к тегу head с атрибутом type и одним простым правилом перехода внутри, который соответствует каждому отдельному id / классу / элементу. Не стесняйтесь изменять свойство 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();
4 голосов
/ 25 февраля 2010

Все хорошо, но для того, чтобы styleNode.cssText работал в IE6 с узлом, созданным javascipt, вам нужно добавить узел в документ, прежде чем устанавливать cssText;

дополнительная информация @ http://msdn.microsoft.com/en-us/library/ms533698%28VS.85%29.aspx

3 голосов
/ 29 мая 2018

Эта функция будет грамматически вставлять CSS каждый раз, когда вы вызываете функцию appendStyle следующим образом: appendstyle('css you want to inject'). это работает путем внедрения узла style в заголовок документа. это метод, подобный тому, что люди используют для отложенной загрузки javascript. он работает последовательно в большинстве браузеров.

appendStyle = function (content) {
      style = document.createElement('STYLE');
      style.type = 'text/css';
      style.appendChild(document.createTextNode(content));
      document.head.appendChild(style);

    }
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

  <h1>this is injected css</h1>
  <p>heloo, this is stuff, hkasjdhakhd</p>
  <button onclick='appendStyle("body {background-color:#ff0000;} h1{font-family:Helvetica, sans-serif;font-variant:small-caps;letter-spacing:3px;color:#ff0000;background-color:#000000;} p {font-family:Georgia, serif;font-size:14px;font-style:normal;font-weight:normal;color:#000000;background-color:#ffff00;}")'>press me to inject css!</button>
</body>

</html>
Вы также можете лениво загружать внешние CSS-файлы, используя следующий фрагмент:

appendExternalStyle = function (content) {
      link = document.createElement('LINK');
      link.rel = 'stylesheet';
      link.href = content;
      link.type = 'text/css'; 
      document.head.appendChild(link);

    }
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>html{font-family: sans-serif; 
font-display: swap;}</style>
</head>
<body>

  <h1>this is injected css</h1>
  <p>heloo, this is stuff, hkasjdhakhd</p>
  <button onclick='appendExternalStyle("data:text/css;base64,OjotbW96LXNlbGVjdGlvbntjb2xvcjojZmZmIWltcG9ydGFudDtiYWNrZ3JvdW5kOiMwMDB9OjpzZWxlY3Rpb257Y29sb3I6I2ZmZiFpbXBvcnRhbnQ7YmFja2dyb3VuZDojMDAwfWgxe2ZvbnQtc2l6ZToyZW19Ym9keSxodG1se2NvbG9yOnJnYmEoMCwwLDAsLjc1KTtmb250LXNpemU6MTZweDtmb250LWZhbWlseTpMYXRvLEhlbHZldGljYSBOZXVlLEhlbHZldGljYSxzYW5zLXNlcmlmO2xpbmUtaGVpZ2h0OjEuNjd9YnV0dG9uLGlucHV0e292ZXJmbG93OnZpc2libGV9YnV0dG9uLHNlbGVjdHstd2Via2l0LXRyYW5zaXRpb24tZHVyYXRpb246LjFzO3RyYW5zaXRpb24tZHVyYXRpb246LjFzfQ==")'>press me to inject css!</button>
</body>

</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...