简体   繁体   中英

Setting “type” property of HTML Style element reset css rules

I have following code:

const head = document.getElementsByTagName('head')[0];
const style = document.createElement('style');
const rules = {
  '.test': 'width: 150px; height: 100px; border: 1px solid red;',
};
let sheet;

head.appendChild(style);

sheet = style.sheet;

for (const rule in rules) {
  sheet.insertRule(`${rule} {${rules[rule]}}`, 0);
}

And it works fine. However, when I set "type" property of HTMLStyleElement after its sheet has been extracted to variable, sheet css rules becomes empty and styles won't be applied to page:

head.appendChild(style);

sheet = style.sheet;
style.type = 'text/css'; // it won't work now!

Why is it happening? Shouldn't sheet reference be assigned to variable?

JsBin link: https://jsbin.com/gehahiceza/edit?html,js,console

okay, so here it is, for reference,https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style

type on the style element is an attribute not a property. the stuff that goes inside of any html element like <img src=""> src is an attribute, not a property of the img element.

so when you try to assign a value to property of the style variable which is a style element, js will just create a property (type) on the style variable then assign the value you give it.


i'm sorry i hadnt answer your question earlier. upon further investigation, i'm finding that.type is already a property on the style element and it should not be used according to whatgw.org and "In particular, a type value with parameters, such as "text/css; charset=utf-8", will cause this algorithm to return early."[ https://html.spec.whatwg.org/multipage/semantics.html#the-style-element] .

i actually observed this behavior from my fiddle where i took your code and added a console.log statement before sheet.insertRule() call and after to see what had happened to style.sheet.

just so we're clear, during.insertRule(), the engine is returning a new style element into the child of the head element. in that case, it is being returned prematurely without the added styles in the for in loop.

interestingly, if you do style.type2 = 'css/text' or whatever text you want. the return of the style.sheet (CSSStyleSheet) would have the added styles in rules: ruleList[] .

i hope this at least provides some additional insights to the reason why the styles arent showing up when doing style.type = 'css/text'

set type property before adding style element to document.

 const head = document.getElementsByTagName('head')[0]; const style = document.createElement('style'); style.setAttribute('type', 'text/css'); //.::;:;:;,;; const rules = { '.test'; 'width. 150px; height. 100px, border; 1px solid red;', }; let sheet; head.appendChild(style); sheet = style.sheet; for (const rule in rules) { sheet.insertRule(`${rule} {${rules[rule]}}`, 0); }
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> </head> <body> <div class="test"> </div> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM