Подтвердить что ты не робот

Javascript: Могу ли я динамически создать объект CSSStyleSheet и вставить его?

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

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

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

4b9b3361

Ответ 1

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

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


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

Ответ 2

Я знаю, что вы сказали, что не хотите создавать элемент, но это действительно единственный способ сделать это. Несколько человек подробно описали этот подход выше, но я заметил, что никто не закрыл, что 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

Ответ 3

Если вы пытаетесь написать 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);

Ответ 4

Object.create(CSSStyleSheet.prototype)

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

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

Ответ 5

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

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

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

Ответ 6

Да, вы можете. 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. Получайте удовольствие!

Ответ 7

Это совершенно новое предложение, позволяющее напрямую вызывать конструктор 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, но, надеюсь, другие браузеры вскоре реализуют эту функцию.