如何仅选择最后一个子元素为影子 DOM 主机元素?

3
我希望仅选择影子DOM宿主元素,但只有当它是最后一个子元素时才选择。
在这个例子中它们都是绿色的,我想让它们都变成红色,除了最后一个。

class MyCustomElement extends HTMLElement {
  constructor(){
    super();
    this.attachShadow({mode: 'open'});
    this.shadowRoot.innerHTML = `
      <h5>Element:</h5>
      <slot></slot>
      <style>
        :host {
          color: red;
        }
        :host-context(:last-child) {
          color: green;
        }
      </style>
     `;
  }
}
window.customElements.define('my-custom-element', MyCustomElement);
<div>
  <my-custom-element>first</my-cutom-element>
  <my-custom-element>... more elements</my-cutom-element>
  <my-custom-element>last</my-cutom-element>
</div>

这些都是绿色的...我只希望最后一个是绿色的。

我也尝试过 :host:last-child,但没有效果,:host-context(my-custom-element:last-child) 也会让它们全部变成绿色。

1个回答

1

请参考我给出的另一个答案中的提示:使用类似于:first-child的CSS选择器在影子DOM内部

你的元素仍然隐藏在光DOM中!
任何全局样式(随时)应用的变化都会反映到影子DOM中

customElements.define('my-custom-element', class extends HTMLElement {
  constructor(){
    super()
      .attachShadow({mode: 'open'})
      .innerHTML = `<slot></slot><style>:host { color: red; }</style>`;
  }
});
<div>
  <my-custom-element>first</my-custom-element>
  <my-custom-element>... more elements</my-custom-element>
  <my-custom-element>last</my-custom-element>
</div>

<style>
   div my-custom-element:last-child {
        padding:    .5em;
        background: green;
   }
</style>

注意:



回复评论:

这可能是真正的答案,但这很糟糕,我原以为影子DOM的整个要点就是自包含性,如果我必须在全局样式表中编写一些样式,然后才能在影子DOM中样式化某些内容,那似乎并不是一个好主意。难怪人们会倾向于像React和Vue这样的东西,因为Web标准太差了。

可以这样想,如果你的my-custom-element<p>元素,那么<p>如何知道它在last-child内部呢?只有通过引用其父容器

难怪人们会倾向于像React和Vue这样的东西,因为Web标准太差了。

所有框架都是一样的,它们将事物包装在容器中(无论是在常规DOM、影子DOM还是虚拟DOM(内存)中)。

更准确地说:框架总是在容器中框定您的内容

原生的W3C标准定制元素API可以完全控制是否使用容器。

是的,这意味着您必须在用餐之前进行一些脚本/烹饪。

您有100%的自由度来决定如何烹饪组件。

React会增加48 KB(GZipped)到您的下载量中,更不用说整个构建过程,更不用说它永远不会与任何其他框架协同工作,更不用说它甚至不再符合ES标准。

额外的定制元素大约需要15分钟和200个字节


这可能是真正的答案,但这很令人失望,我认为 Shadow DOM 的整个重点是自包含性,如果我必须在全局样式表中编写一些样式,然后才能对 Shadow DOM 中的某些内容进行样式化,那似乎不是一个好的交易,难怪人们会倾向于像 React 和 Vue 这样的东西,当 Web 标准如此之低劣时。 - Dustin Poissant
我想我会写一些JavaScript来生成内联样式,因为我不会将其包含在全局样式表中以便在99%的页面上都不会有自定义元素时发送到所有页面,而且在使用自定义元素后我也不会在HTML文档本身中编写样式标签。我宁愿在一个JS文件中完成所有事情。 - Dustin Poissant
添加了回复在答案中。 - Danny '365CSI' Engelman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接