在connectedCallback中等待元素升级。FireFox和Chromium的区别

问题描述 投票:1回答:1

在FireFox中呆了一个星期后,又被这个Chrome元素升级问题咬住了。

在交付给Chromium浏览器之前,忘了用setTimeout包裹代码。

  • FireFox打印。ABCD

  • 铬版画。ADCD

问题。 如果FireFox能够表现出一个开发者所期望的样子。为什么呢? Chromium有什么不同吗?

<script>
  customElements.define('my-element', class extends HTMLElement {
    connectedCallback() {
      console.log(this.innerHTML);// "A" in FireFox, "" in other Browsers
      if (this.innerHTML == "A")
        this.innerHTML = this.innerHTML + "B";
      else
        setTimeout(() => this.innerHTML = this.innerHTML + "D");
    }
  })
</script>

<my-element>A</my-element><my-element>C</my-element>

过去几年的相关回答。

更新#1

  • AppleSafari:打印。ADCD

注:Chromiums Blink引擎是苹果公司的一个分叉点 (WebKit)WebCore 代码 所以,原因可能比Custom Elements更深层次(我们可以再次责怪苹果吗?

更新#2

通过Supersharps参考,我们找到了相关的线程。

google-chrome web-component custom-element
1个回答
1
投票

我认为ChromeSafari的行为对于初学者来说不那么直观,但对于一些更复杂的场景(例如与子自定义元素),那么它就会更加一致。

请看下面的不同例子。它们在Firefox中的行为很奇怪......

另一个我没有勇气编写代码的用例:当一个文档被解析时,也许你还没有看到文档的结尾。因此,当一个自定义元素被创建时,你不能确定你得到了它的所有子元素,直到你得到结束标签(可能永远不会到达)。

根据Ryosuke Niwa for WebKit的说法。

那么问题就在于,元素不会得到connectedCallback,直到所有的子元素都被解析出来。例如,如果整个文档是一个单一的自定义元素,那么在整个文档被获取&解析之前,该自定义元素永远不会收到connectedCallback,即使该元素真的在文档中。这样就不好了。

所以最好不要等待,一旦创建了自定义元素,也就是在没有子元素的情况下,立即连接。

<script>
    customElements.define( 'c-e', class extends HTMLElement {} ) 
    customElements.define('my-element', class extends HTMLElement {
      connectedCallback() {
        console.log(this.innerHTML, this.childNodes.length)
        let span = document.createElement( 'span' )
        if (this.innerHTML.indexOf( 'A' ) >= 0 )
            span.textContent = 'B'
        else
            span.textContent = 'D'
        setTimeout( () => this.appendChild( span ) )
      }
    })
</script>
<my-element>A</my-element><my-element>C</my-element>
<br>
<my-element><c-e></c-e>A</my-element><my-element>A<c-e></c-e></my-element>
<br>
<my-element><c-e2></c-e2>A</my-element><my-element>A<c-e2></c-e2></my-element>

据我所知,大家对此达成了共识,所以才调整了规范(ChromeSafari)的方式。

修复 w3cwebcomponents#551 确保插入DOM的元素会立即触发connectCallback,而不是将回调反应放在备份元素队列中,让它在下一个微任务检查点被触发。这意味着connectCallback一般会像预期的那样,在元素的子代为零时被调用,而不是根据下一个自定义元素被看到时的随机数。

我们可以得出结论,Firefox也遵循了规范......是的,但我们不应该依赖在 connectedCallback 出于上述原因。

© www.soinside.com 2019 - 2024. All rights reserved.