Back

Technologies:

javascriptjavascript
avatar
Tolerim
a month ago

Is it possible to assign a distinctive identifier to a Constructable Stylesheet?

Initial Setup and Question

When injecting multiple components into a document through user interaction, each component will have its own associated Constructable Stylesheet. However, these interactions may be repeated and the same component markup may be injected any number of times. Therefore, the associated constructable stylesheet need only be constructed and adopted once for a single component. I would like to identify each constructable stylesheet uniquely, perhaps through a unique title property, so that I can check the existing document.adoptedStyleSheets and ensure that the same stylesheet is not constructed and adopted again. How can I add or edit properties of the CSSStyleSheet object for this purpose?


Possible Solution

I have attempted to add or edit properties of the CSSStyleSheet object, but none of my attempts have been successful. However, I thought of an alternative solution. Instead of assigning a unique label to the componentAStylesheet object, I can create a parent object and manually add an entry for each component-associated stylesheet. For example, after creating a new CSSStyleSheet object for component A:

const componentAStylesheet = new CSSStyleSheet();
I can create a parent object:

const myComponents = {}
and manually add the following entry:

myComponents['componentA'] = componentAStylesheet;
By doing so, I can later check if each component-associated stylesheet has already been constructed and adopted by the document. While I have not found a way to label the constructed stylesheet object itself, this alternative solution achieves the same goal with a slightly different approach.

Answers(2)
avatar
Vogi
a month ago
Verified Answer
You can use the CSSStyleSheet() constructor to create a new CSSStyleSheet object which represents a single Stylesheet. After constructing a stylesheet, you can use the CSSStyleSheet.replace(), CSSStyleSheet.replaceSync(), CSSStyleSheet.insertRule(), and CSSStyleSheet.deleteRule() methods to modify the rules of the new stylesheet. However, I think your alternative solution of creating a parent object and manually adding an entry for each component-associated stylesheet is also a good approach. By doing so, you can later check if each component-associated stylesheet has already been constructed and adopted by the document. While you have not found a way to label the constructed stylesheet object itself, this alternative solution achieves the same goal with a slightly different approach. I hope this helps! Let me know if you have any other questions.

Sources

CSSStyleSheet: CSSStyleSheet() constructor - Web APIs | MDNmodify a css rule object with javascript - Stack OverflowCSSStyleSheet - Web APIs | MDN - Mozilla Developerdom - Javascript: Can i dynamically create a CSSStyleSheet object and ...
avatar
Tolerim
a month ago
To uniquely identify each constructable stylesheet, you can use the replaceSync() method to insert a unique identifier into the CSS rule block of the style sheet. Here's an example:
const componentAStylesheet = new CSSStyleSheet();
componentAStylesheet.replaceSync(`/* Component A Stylesheet */`);
In this example, we are manually adding a unique label to the CSS rule block of the style sheet by passing the string '/* Component A Stylesheet */' as an argument to replaceSync(). You can replace this string with any unique identifier of your choice. You can then check if the stylesheet has already been adopted by the document by comparing its cssRules property to those of other stylesheets in the document.adoptedStyleSheets array:
const alreadyAdopted = document.adoptedStyleSheets.some(
  (styleSheet) => styleSheet.cssRules.join('') === componentAStylesheet.cssRules.join('')
);

if (alreadyAdopted) {
  // Do something...
} else {
  document.adoptedStyleSheets = [...document.adoptedStyleSheets, componentAStylesheet];
}
In this example, we are using the some() method to check if any of the stylesheets in document.adoptedStyleSheets have the same rules as componentAStylesheet. If a match is found, we know that componentAStylesheet has already been adopted and we can skip adding it again. Otherwise, we add it to the array using the spread operator.
;