有什么方法可以像使用 attributeChangedCallback 处理属性一样处理 CSS 应用于 Web 组件的方式吗? .
我正在开发几个 Web 组件,这些组件将受益于使用 CSS 类设置样式,但我需要更改多种样式以使其看起来正确(例如,如果您设置控件的颜色,用户会期望边框一个元素的颜色和另一个元素的字体颜色在阴影 DOM 中改变)。
有什么方法可以得到 .usingCSS { color: red; }
更改以下简单 Web 组件示例中切换开关的颜色?
// based on https://www.w3schools.com/howto/howto_css_switch.asp
class W3schoolsToggleSwitch extends HTMLElement {
constructor() {
super();
var shadow = this.attachShadow({ mode: "open" });
this.span = document.createElement("span");
this.span.innerHTML = `
<style>
/* The switch - the box around the slider */
.switch {
--color: #2196F3;
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: var(--color);
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
</style>
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
`;
shadow.appendChild(this.span);
}
static get observedAttributes() {
return ["color"];
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(name, newValue);
if ("color" === name) {
this.shadowRoot
.querySelector(".switch")
.style.setProperty("--color", newValue);
}
}
get color() {
return this.getAttribute("color");
}
set color(value) {
return this.setAttribute("color", value);
}
}
customElements.define("w3schools-toggle-switch", W3schoolsToggleSwitch);
.usingCSS {
color: red;
}
default:
<w3schools-toggle-switch></w3schools-toggle-switch>
<br><br> color attribute used to change the color to green:
<w3schools-toggle-switch color="green"></w3schools-toggle-switch>
<br><br> can you change the color with CSS?:
<w3schools-toggle-switch class="usingCSS"></w3schools-toggle-switch>
最佳答案
从外面用 <
链接 >
您可以使用 <link>
将 CSS 样式应用于 Web 组件Shadow DOM 中的元素。
#shadow-root
<link rel="stylesheet" href="default.css">
attributeChangedCallback( name, old, value ) {
if (name === 'class')
this.shadowRoot.querySelector( 'link' ).href = value + ".css"
}
在 Shadow DOM 中定义样式 :host()伪类函数
您可以根据上下文应用不同的样式。您可以组合多个类。
customElements.define( 'custom-element', class extends HTMLElement {
constructor() {
super()
this.attachShadow( { mode: 'open' } )
.innerHTML = `
<style>
:host( .red ) { color: red }
:host( .blue ) { color: blue }
:host( .border ) { border: 1px solid }
</style>
Hello`
}
} )
ce1.onclick = ev => ev.target.classList.add( 'border' )
<custom-element class="red" id="ce1"></custom-element>
<custom-element class="blue border"></custom-element>
在 Chrome/Opera 上:使用 Constructable stylesheets
创建一个(或多个)样式表并将其应用到 Shadow DOM。您可以将多个样式表应用于同一个 Shadow DOM。
var ss = []
ss['red'] = new CSSStyleSheet
ss.red.replaceSync( 'span { color: red }' )
ss['green'] = new CSSStyleSheet
ss.green.replaceSync( 'span { color: green }' )
ss['border'] = new CSSStyleSheet
ss.border.replaceSync( 'span { border: 1px solid }' )
customElements.define( 'custom-element', class extends HTMLElement {
constructor() {
super()
this.attachShadow( { mode: 'open' } )
.innerHTML = `<span>Hello</span>`
}
static get observedAttributes() { return [ 'class' ] }
attributeChangedCallback() {
this.shadowRoot.adoptedStyleSheets = [ ...this.classList ].map( cl => ss[ cl ] )
}
} )
ce1.onclick = ev => ev.target.classList.add( 'border' )
<custom-element class="red" id="ce1"></custom-element>
<custom-element class="green border"></custom-element>
关于javascript - Web 组件可以处理 CSS(cssChangedCallback 吗?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58921620/