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?
Ответы
Ответ 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, но, надеюсь, другие браузеры вскоре реализуют эту функцию.