疑似Chrome漏洞:CSS "last-of-type"未在Web组件上更新

dsekswqp  于 2023-03-06  发布在  Go
关注(0)|答案(2)|浏览(151)

下面你会看到一个灰色块的列表,项目111555。运行2秒后,另一个项目将通过JS创建并添加到列表中。NEW项目将被样式化为last-of-type,但之前的last-of-type将保持样式化,好像是最后一个类型,但它不再是!
我目前的修复是当附加一个新的项目到列表,隐藏旧的最后一个项目(555)在这种情况下,然后再次显示它,这是通过设置display: none然后display: block完成的。不幸的是,它导致 Flink 更复杂的网页组件。有没有办法使last-of-type更新 Flink ?我使用last-of-type不正确?这是一个Chrome的错误?

class Component extends HTMLElement {
    constructor() {
    super().attachShadow({mode:'open'});
    const template = document.getElementById("TEMPLATE");
    this.shadowRoot.appendChild(template.content.cloneNode(true));
  }
}
window.customElements.define('wc-foo', Component);

setTimeout( () => {
   const child = document.createElement('div')
   child.textContent = "new"
   child.classList.add('child')
   CONTAINER.appendChild(child)
}, 2000)
#CONTAINER .child:last-of-type {
   border: 1px solid red;
}
<template id="TEMPLATE">
  <style>
      :host {
        background: gray;
        display: block;
      }
  </style>
  <slot>
   WC-FOO
  </slot>
</template>

<div id="CONTAINER">
    <wc-foo class="child">111</wc-foo>
    <wc-foo class="child">222</wc-foo>
    <wc-foo class="child">333</wc-foo>
    <wc-foo class="child">444</wc-foo>
    <wc-foo class="child">555</wc-foo>
</div>

同时打开此错误报告:https://bugs.chromium.org/p/chromium/issues/detail?id=1417953

yvgpqqbh

yvgpqqbh1#

这不是一个bug,它正在按设计(和预期)工作。:last-of-type引用元素的元素类型,而不是类名;因此,最后的wc-foo-不管其类名如何-即使当它具有相同类名的相邻兄弟时也保持:last-of-type;正如文档所述:
... :last-of-type伪类表示其类型的最后一个同级元素。
引文:https://www.w3.org/TR/selectors-3/#last-of-type-pseudo。
为了演示,我们可以添加<wc-foo>元素来代替<div>元素:

class Component extends HTMLElement {
  constructor() {
    super().attachShadow({
      mode: 'open'
    });
    const template = document.getElementById("TEMPLATE");
    this.shadowRoot.appendChild(template.content.cloneNode(true));
  }
}
window.customElements.define('wc-foo', Component);

setTimeout(() => {
  const child = document.createElement('wc-foo')
  child.textContent = "new"
  child.classList.add('child')
  CONTAINER.appendChild(child)
}, 2000)
#CONTAINER .child:last-of-type {
  border: 1px solid red;
}
<template id="TEMPLATE">
  <style>
    :host {
      background: gray;
      display: block;
    }

  </style>
  <slot>
    WC-FOO
  </slot>
</template>

<div id="CONTAINER">
  <wc-foo class="child">111</wc-foo>
  <wc-foo class="child">222</wc-foo>
  <wc-foo class="child">333</wc-foo>
  <wc-foo class="child">444</wc-foo>
  <wc-foo class="child">555</wc-foo>
</div>

JS Fiddle demo .
参考文献:

hxzsmxv2

hxzsmxv22#

如果Chromium团队认为这是一个bug,我会非常惊讶。

  • 一个<wc-foo>就是
  • 并且您添加的<div>last-of-type

您的最小代码:

#CONTAINER .child:last-of-type {
   border: 1px solid red;
}

:最后一个子级将为您获得最后一个子级

<div id="CONTAINER">
  <wc-foo class="child">111</wc-foo>
  <wc-foo class="child">222</wc-foo>
  <wc-foo class="child">333</wc-foo>
  <wc-foo class="child">444</wc-foo>
  <wc-foo class="child">555</wc-foo>
  <b class="child">LAST</b>
</div>

<style>
.child:last-child {
  background:lightgreen
}
</style>

相关问题