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

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

问题描述

更新2021年3月

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

这意味着等待 connectedCallback 中的JS EventLoop为空(带有 setTimeout requestAnimationFrame )现在是唯一的跨浏览器方法

事件循环到底是什么?-菲利普·罗伯茨
插入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 the only cross-browser method

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



Update Oct. 28 2020:

First post:

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天全站免登陆