簡體   English   中英

Javascript:我可以動態創建一個 CSSStyleSheet 對象並插入它嗎?

[英]Javascript: Can i dynamically create a CSSStyleSheet object and insert it?

我知道document.styleSheets由頁面中的所有有效樣式表組成。 我想知道我是否可以創建一個新的並通過 javascript 將其附加到當前列表中。

我試過document.styleSheets[0].constructor , document.styleSheets[0].__proto__.constructor , new CSSStyleSheet , CSSStyleSheet() ,我從 Chrome 得到的都是TypeError: Illegal constructor CSSStyleSheet.constructor()返回一個純對象,但我期望一個 CSSStyleSheet 對象。

我知道我可以創建一個鏈接/樣式元素並附加它,然后修改它。 我想知道的是,我可以直接用 javascript 創建這樣的對象嗎?

我知道你說過你不想創建一個元素,但這確實是唯一的方法。 一些人在上面詳細介紹了這種方法,但我注意到沒有人掩蓋HTMLStyleElementHTMLLinkElement都有一個整潔的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搜索要簡單得多

一個全新的提議可以直接調用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,但希望其他瀏覽器能盡快實現此功能。

如果您嘗試在 javascript 中編寫 css,請執行以下操作:

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);

是的你可以。 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);

如果您運行 Firefox,您可以直接在 Scratchpad 中進行測試:復制代碼,按Shift+F4 ,粘貼它,然后使用Ctrl+L運行代碼。 玩得開心!

據我所知,唯一接近您要求的方法是IE-only document.createStyleSheet([url] [,index])方法,您可以使用該方法創建最多 31 * styleSheet對象(之后您仍然需要手動創建style元素並將它們附加到document )。

這個答案顯示了如何為非 IE 瀏覽器定義createStyleSheet()方法,但正如您所期望的那樣,它通過附加link / style元素(出於某種原因您試圖避免)來實現。


* 由於用於存儲工作表 ID 的 5 位字段, IE 6 到 9 僅限於 31 個導入的樣式表。 在 IE10 中,此限制已提高到 4095。

你試過這個嗎:

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

假設 document.styleSheets[0] 是一個 CSSStyleSheet 對象,實際上如果您將 document.styleSheets[0] 替換為任何 CSSStyleSheet 它將起作用。

Object.create(CSSStyleSheet.prototype)

返回一個空的 CSSStyleSheet 實例。 換句話說,它所做的正是您期望new CSSStyleSheet所做的。

Object.create可在任何支持 ECMAScript 5 的瀏覽器中使用。 在此處查找兼容性表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM