JavaScript: Могу ли я динамически создать объект CSSStyleSheet и вставить его? - PullRequest
19 голосов
/ 21 ноября 2011

Я знаю document.styleSheets, который состоит из всех допустимых таблиц стилей на странице.Я хочу знать, могу ли я создать новый и добавить его в настоящий список через javascript.

Я пробовал document.styleSheets[0].constructor, document.styleSheets[0].__proto__.constructor, new CSSStyleSheet, CSSStyleSheet(), все, что я получаю отХром это TypeError: Illegal constructor.CSSStyleSheet.constructor() вернул чистый объект, но я ожидаю объект CSSStyleSheet.

Я знаю, что могу создать элемент link / style и добавить его, а затем изменить его.Что я хочу знать, так это то, могу ли я создать такой объект напрямую с помощью JavaScript?

Ответы [ 7 ]

14 голосов
/ 18 июня 2014

Я знаю, что вы сказали, что не хотите создавать элемент, но это действительно единственный способ сделать это.Несколько человек подробно описали этот подход выше, но я заметил, что никто не скрывал, что HTMLStyleElement и HTMLLinkElement оба имеют аккуратное sheet свойство для прямого доступа к своим CSSStyleSheet:

var style = document.createElement("style");
document.head.appendChild(style); // must append before you can access sheet property
var sheet = style.sheet;

console.log(sheet instanceof CSSStyleSheet);

Гораздо проще, чем поиск по document.styleSheets

5 голосов
/ 21 ноября 2011

Если вы пытаетесь написать CSS внутри javascript, сделайте это:

var s = document.createElement('style');
s.type = 'text/css';
s.innerText = 'body { background: #222; } /*... more css ..*/';
document.head.appendChild(s);

Принимая во внимание, что если вы пытаетесь загрузить таблицу стилей с сервера:

var s = document.createElement('link');
s.type = 'text/css';
s.rel = 'stylesheet';
s.href = '/url/to/css/file.css';
document.head.appendChild(s);
3 голосов
/ 17 февраля 2014

Object.create(CSSStyleSheet.prototype)

возвращает вам пустой экземпляр CSSStyleSheet.Другими словами, он делает именно то, что вы ожидаете от new CSSStyleSheet.

Object.create доступен в любом браузере с поддержкой ECMAScript 5.Найти таблицу совместимости здесь .

3 голосов
/ 21 ноября 2011

Насколько я знаю, единственный подход, который приближается к тому, что вы запрашиваете, - это IE-only document.createStyleSheet([url] [,index]) метод, который вы можете использовать для создания до 31 * styleSheet объектов (после чего вам все равно придется вручную создавать style элементы и добавлять их к document).

В этом ответе показано, как можно определить метод createStyleSheet() для браузеров, отличных от IE, но, как и следовало ожидать, это делается путем добавления элементов link / style (что по какой-то причине ты пытаешься избежать).


* IE 6–9 ограничен 31 импортированной таблицей стилей из-за 5-битного поля, используемого для хранения идентификаторов листа . В IE10 этот предел был увеличен до 4095.

2 голосов
/ 12 января 2019

Существует новое предложение , которое позволяет напрямую вызывать конструктор CSSStyleSheet. Делать то, что вы хотите, выглядит следующим образом:

// Construct the CSSStyleSheet
const stylesheet = new CSSStyleSheet();

// Add some CSS
stylesheet.replaceSync('body { background: #000 !important; }')
// OR stylesheet.replace, which returns a Promise instead

// Tell the document to adopt your new stylesheet.
// Note that this also works with Shadow Roots.
document.adoptedStyleSheets = [stylesheet];

Обратите внимание, что в настоящее время это работает только на Chrome Canary, но, надеюсь, другие браузеры вскоре реализуют эту функцию.

2 голосов
/ 02 июля 2013

Да, вы можете.document.styleSheets нельзя изменить напрямую, но вы можете добавить запись, добавив новый тег стиля в ваш документ:

// Create the style element
var elem = $('<style id="lwuiStyle"></style>');
$('head').append(elem);

// Find its CSSStyleSheet entry in document.styleSheets
var sheet,
    yourSheet = null;
for (var sid in document.styleSheets) {
    if (document.styleSheets.hasOwnProperty(sid)) {
        sheet = document.styleSheets[sid];
        if (sheet.ownerNode == elem[0]) {
            yourSheet = sheet;
            break;
        }
    }
}

// Test it by changing the background colour
yourSheet.insertRule('body {background-color: #fa0}', yourSheet.cssRules.length);

Если вы запустите Firefox, вы можете напрямую проверить это в Scratchpad: Скопируйте коднажмите Shift+F4, вставьте его и запустите код с Ctrl+L.Веселись!

2 голосов
/ 05 февраля 2013

Вы пробовали это:

var myCSSStyleSheetIbj = Object.create(document.styleSheets[0])

Предполагая, что document.styleSheets [0] является объектом CSSStyleSheet, На самом деле, если вы замените document.styleSheets [0] на любой CSSStyleSheet, он будет работать.

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