如果您正在创建一个不使用 ShadowDOM 的组件,您可能仍需要将 CSS 添加到 shadowRoot 中。如果其他人将您的组件放入他们的 shadowDOM 中,那么您必须将您的 CSS 添加到他们的 shadowRoot 中。您可以使用以下代码执行此操作:
const myStyle = document.createElement('style');
myStyle.setAttribute('component', 'my-el');
myStyle.textContent = ` button {
padding: 8px 20px;
}
.happy-btn {
background-color: pink;
}
.sad-btn {
background-color: #007;
color: white;
}`;
function addCss(el, selector, styleEl) {
// Check to see if we have been placed into a shadow root.
// If we have then add our CSS into that shadow root.
let doc;
try {
doc = el.getRootNode();
if (doc === document) {
doc = document.head;
}
}
catch(_ex) { doc = document.head; } // Shadow DOM isn't supported.
if (!doc.querySelector(selector)) {
doc.appendChild(styleEl.cloneNode(true));
}
}
class MyEl extends HTMLElement {
constructor() {
super();
addCss(this, 'style[component="my-el"]', myStyle);
}
connectedCallback() {
this.innerHTML = `<div class="spaced"><button class="happy-btn">I'm Happy</button></div>
<div class="spaced"><button class="sad-btn">I'm Sad</button></div>`;
}
}
customElements.define('my-el', MyEl);
class TheirEl extends HTMLElement {
constructor() {
super();
this.attachShadow({mode:'open'});
this.shadowRoot.innerHTML = `<hr/><my-el></my-el><hr/><my-el></my-el><hr/>`;
}
}
customElements.define('their-el', TheirEl);
<their-el></their-el>
该函数addCss
会将您的 CSS 放入正确的 shadowRoot 中,或者document.head
如果没有 shadowRoot 则放入。
您必须addCss
在构造函数中调用以将 CSS 放置在正确的位置。只要您有一个唯一的选择器来识别您的<style>
标签,此例程还将确保您不会将其添加两次。
在我的中,您会看到该<style>
标签添加了一个属性,该属性component
使用组件名称的值调用。就我而言component="my-el"
。
然后我使用选择器 'style[component="my-el"]' 来查看该标签是否已经在 shadowRoot 中,或者document.head
是否没有 shadowRoot,如果样式不存在,则仅添加样式。
你不能仅仅因为你没有使用它就假设你的组件不会在 shadow DOM 中。使用上面的示例来保护自己。
边注
如果您使用的是 shadow DOM,那么这个问题就会消失,因为您必须将 CSS 放入自己的 shadowRoot 中。