在 connectedCallback 中等待元素升级:FireFox 和 Chromium 的区别 [英] wait for Element Upgrade in connectedCallback: FireFox and Chromium differences

查看:22
本文介绍了在 connectedCallback 中等待元素升级:FireFox 和 Chromium 的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

2021 年 3 月更新:

修复了 FireFox 错误,现在其行为与 Chromium 和 Safari 相同.

这意味着在 connectedCallback 中等待 JS EventLoop 为空(使用 setTimeoutrequestAnimationFrame)现在是一个跨浏览器的方法

connectedCallback(){setTimeout(()=>{//可以在这里访问 lightDOM});//,0 不需要}

事件循环到底是什么?- 菲利普·罗伯茨
,确保插入 DOM 会立即触发 connectedCallback,而不是将回调反应放在备份元素队列上,让它在下一个微任务检查点被触发.这意味着当元素为零时,通常会调用 connectedCallback孩子,正如预期的那样,而不是随机数,这取决于什么时候看到下一个自定义元素.

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

Update March 2021:

FireFox bug fixed, now behaves the same as Chromium and Safari.

That means waiting for the JS EventLoop to be empty (with setTimeout or requestAnimationFrame) in the connectedCallback is now a cross-browser method

connectedCallback(){
 setTimeout(()=>{
   // can access lightDOM here
 }); // ,0 not required
}

What the heck is the Event Loop? - Philip Roberts
https://www.youtube.com/watch?v=8aGhZQkoFbQ



Update Oct. 28 2020:



First post May. 2020:

Bitten again by this Chrome Element upgrade issue, after spending a week in FireFox.

Forgot to wrap code in a setTimeout before delivering to Chromium browsers.

  • FireFox prints: ABCD

  • Chromium prints: ADCD

Question: Why the difference?

<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>

Related answers over the past years:

Update #1

  • Apple/Safari: prints: ADCD (same as Chromium)

note: Chromium Blink engine is a fork of Apples (WebKit)WebCore code!!

Update #2

With Supersharps reference we found the related threads:

order of callbacks in FireFox versus Chromium:

source: https://jsfiddle.net/CustomElementsExamples/n20bwckt/

解决方案

I think the Chrome/Safari behaviour is less intuitive for the beginners, but with some more complex scenarios (for example with child custom elements) then it is much more consistant.

See the different examples below. They act strangely in Firefox...

Another use case that I don't have the courage to code: when a document is parsed, maybe you don't have the end of the document yet. Therefore, when a custom element is created, you cannot be sure you get all its children until you get the closing tag (that could never arrive).

According to Ryosuke Niwa for WebKit:

The problem then is that the element won't get connectedCallback until all children are parsed. For example, if the entire document was a single custom element, that custom element would never receive connectedCallback until the entire document is fetched & parsed even though the element is really in the document. That would be bad.

So it's better no to wait and connect the custom element as soon as it is created, that means with no child.

<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>

As far as I understand, there was a consensus on it that led to adjust the spec that (Chrome/Safari) way:

Fixes w3c/webcomponents#551 by ensuring that insertions into the DOM trigger connectedCallback immediately, instead of putting the callback reaction on the the backup element queue and letting it get triggered at the next microtask checkpoint. This means connectedCallback will generally be invoked when the element has zero children, as expected, instead of a random number depending on when the next custom element is seen.

We can conclude that Firefox also follow the spec... yes, but we should not rely on the content in connectedCallback for the reasons discussed above.

这篇关于在 connectedCallback 中等待元素升级:FireFox 和 Chromium 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆