我的
<web-component></webcomponent>
搭建起来非常简单,一系列的<input type="text part="input" />
直接在#shadow-root
中。
我可以将它们全部组合在一起,没有任何麻烦:
web-component::part(input) {
border: 1px solid #000
}
但是如果我想针对特定输入,这些都不起作用:
web-component::part(input):nth-child(3) {}
web-component::part(input):nth-of-type(3) {}
web-component::part(input).input-3 {} /* with class properly defined in the web component */
web-component::part(input.input-3) {}
web-component::part(input:nth-of-type(3)) {}
...
找不到任何有关此的文档。
编辑:我忘了提及输入没有被插入,它们是动态生成的。
customElements.define("web-component",
class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: "open"});
this.size = this.getAttribute('size');
this.template = document.createElement("template");
this.template.innerHTML = '<style>'
+':host {white-space: nowrap}'
+'input {text-align:center;width: 3ch;height: 3ch}'
+'input:not(:last-child){margin-right:.5ch}'
+'</style>'
this.render();
}
render() {
this.shadowRoot.appendChild(this.template.content.cloneNode(true));
for (let i = 0; i < this.size; i++) {
const input = document.createElement('input');
input.setAttribute('part','input');
input.classList.add('input-'+(i+1));
input.type = "text";
this.shadowRoot.appendChild(input);
}
}
}
);
web-component::part(input) {
border: 2px solid orange;
}
web-component::part(input):nth-child(1) {
background: #ff00ff;
}
web-component::part(input):nth-of-type(2) {
background: #ff0000;
}
web-component::part(input).input-3 {
background: #00ff00;
}
web-component::part(input.input-4) {
background: #00ffff;
}
web-component::part(input:nth-of-type(5)) {
background: #ff00ff;
}
web-component::part(input:nth-chlid(6)) {
background: #ff0000;
}
<web-component size="6"></web-component>
这是做不到的。来自 W3C css-shadow-parts 规范:
::part() 伪元素可以在其后添加额外的 pseudo 类,例如 x-button::part(label):hover,但永远不会与结构伪类或任何其他伪类匹配基于树信息而不是局部元素信息进行匹配。
您可以考虑添加第二部分,例如
input input-1
。部件名称的作用与类类似:多个元素可以具有相同的部件名称,并且单个元素可以具有多个部件名称。 (也来自相同的规格。)
customElements.define("web-component",
class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: "open"});
this.size = this.getAttribute('size');
this.template = document.createElement("template");
this.template.innerHTML = '<style>'
+':host {white-space: nowrap}'
+'input {text-align:center;width: 3ch;height: 3ch}'
+'input:not(:last-child){margin-right:.5ch}'
+'</style>'
this.render();
}
render() {
this.shadowRoot.appendChild(this.template.content.cloneNode(true));
for (let i = 0; i < this.size; i++) {
const input = document.createElement('input');
input.setAttribute('part','input input-'+(i+1));
input.type = "text";
this.shadowRoot.appendChild(input);
}
}
}
);
web-component::part(input input-1) {
background: #ff00ff;
}
web-component::part(input) {
border: 2px solid orange;
}
<web-component size="6" id="shadow-dom-host"></web-component>