Javascript:我可以动态创建CSSStyleSheet对象并插入它吗?

aya*_*ist 19 javascript dom

我知道document.styleSheets哪个页面包含所有有效的样式表.我想知道我是否可以创建一个新的并通过javascript将其附加到列表中.

我已经试过document.styleSheets[0].constructor,document.styleSheets[0].__proto__.constructor,new CSSStyleSheet,CSSStyleSheet(),全部是我从Chrome中得到的是TypeError: Illegal constructor.CSSStyleSheet.constructor()返回一个纯对象,但我期待一个CSSStyleSheet对象.

我知道我可以创建一个链接/样式元素并附加它,然后修改它.我想知道的是,我可以直接用javascript创建这样的对象吗?

Wic*_*ams 16

我知道你说你不想创造一个元素,但这真的是唯一的方法.有些人已经详细介绍了上述方法,但我注意到没有人覆盖它,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);
Run Code Online (Sandbox Code Playgroud)

比搜索更简单 document.styleSheets

  • 此外,如果您不想对当前文档产生视觉影响,则可以将 style.disabled 属性设置为 true。 (2认同)

小智 12

一个全新的提议可以直接调用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];
Run Code Online (Sandbox Code Playgroud)

请注意,目前这仅适用于 Chrome Canary,但希望其他浏览器能尽快实现此功能。


reg*_*ity 6

如果您尝试在javascript中编写css,请执行以下操作:

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

而如果您尝试从服务器加载样式表:

var s = document.createElement('link');
s.type = 'text/css';
s.rel = 'stylesheet';
s.href = '/url/to/css/file.css';
document.head.appendChild(s);
Run Code Online (Sandbox Code Playgroud)

  • 不要使用`innerText`,它不是任何标准的一部分,并且没有完全的浏览器兼容性.使用`s.appendChild(document.createTextNode(styles))`进行完全compat. (4认同)

Sim*_*ter 5

是的你可以。不能document.styleSheets直接修改,但您可以通过向文档添加新的样式标签来添加条目:

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

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

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

如果您运行 Firefox,则可以直接在 Scratchpad 中测试:复制代码,按Shift+F4,粘贴它,然后使用 运行代码Ctrl+L。玩得开心!


Sha*_*hin 3

据我所知,接近您要求的唯一方法是仅 IE document.createStyleSheet([url] [,index])方法,您可以使用它来创建最多 31 个* styleSheet对象(之后您仍然需要手动创建style元素并附加他们到document)。

这个答案显示了如何createStyleSheet()为非 IE 浏览器定义该方法,但正如您所期望的那样,它是通过附加link/style元素来实现的(出于某种原因,您试图避免这样做)。


* IE 6 至 9由于用于存储工作表 ID 的 5 位字段而仅限于 31 个导入样式表。在 IE10 中,此限制已提高到 4095。

  • _*眨*_。IE 仍然给我留下了深刻的印象。 (6认同)