Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
324 views
in Technique[技术] by (71.8m points)

callback - wait for Element Upgrade in connectedCallback: FireFox and Chromium differences

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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...