I am new to web development and recently I have been seeing much debate and talks about Custom Elements v1. They allow you to define your own elements with their own custom behaviors and if Shadow DOM is used, with scoped styles.
When I was learning about it in this site, I did not understand the table under "Custom element reactions". Can anyone please explain the difference between using the "constructor" and "connectedCallback" and also the terms "created or upgraded" and "inserted into the DOM"?.
For extra information, my custom element's definition is in a separate file and it uses shadow DOM. I used HTML Import to import the element's definition into the main document.

- 29,002
- 9
- 92
- 134

- 503
- 1
- 5
- 7
-
7constructor gets called if you do something like var button = document.createElement('fancy-button'), whereas connectedCallback would only be called once you do document.body.appendChild(button); That is, it is appended to an element in the dom. – juvian Nov 08 '16 at 16:55
-
1What if we declare the tag directly in the main document as "
"? – Shashank Nov 08 '16 at 17:00 -
1Seems in that case there is no real difference save that one is called before the other : https://jsfiddle.net/ddjvxkpd/ – juvian Nov 08 '16 at 17:16
1 Answers
As already stated by Juvian in the comments:
constructor()
is called when the element is created.connectedCallback()
is called when (after) the element is attached to the DOM.
The constructor()
call is not specific to Custom Elements, it occurs with any object creation (typically created with the new
operator), and not only HTML Elements.
In the constructor()
call, you can create the Shadow DOM, but you can't add Nodes inside the normal DOM, and you can't add or set an attribute either.
About upgrade:
The upgrade occurs when an unknown tag declared in the HTML code is defined afterwards (by the customElements.define()
method). The "unknown" element becomes a "custom" element. The constructor()
and connectedCallback()
methods are then called.
Note: when an element is created (as unknown), and then defined, it is upgraded only when attached.
class CE extends HTMLElement {
constructor() {
super()
console.info( 'constructed' )
}
connectedCallback() {
console.info( 'connected' )
this.innerHTML = 'Hello' //can't be set in constructor()
}
}
B1.onclick = function () {
ce = document.createElement( 'c-e' )
ce.textContent = 'unknown'
}
B2.onclick = function () {
document.body.appendChild( ce )
}
B3.onclick = function () {
customElements.define( 'c-e', CE)
}
<button id=B1>create</button>
<button id=B2>attach</button>
<button id=B3>define</button>
Try different combinations with the above snippet:
- Run then: 1 Create - 2 Attach - 3 Define
- Run then: 1 Create - 2 Define - 3 Attach
- Run then: 1 Define - 2 Create - 3 Attach

- 14,775
- 6
- 54
- 64

- 29,002
- 9
- 92
- 134
-
4
-
2@kzh only if you define the custom element after its rendering (i.e. upgrade of an unknown element). it's not the more frequent use case, and not supported by the spec. – Supersharp Nov 09 '17 at 22:23
-
@Supersharp Is there a simple way to pass values from the HTML to the constructor? Ie, `` and then the constructor has access to the id? It seems silly to find out id only in connected callback – Big Guy Apr 09 '19 at 00:40
-
@BigGuy maybe you should formulate a question, I don't see what you want exactly – Supersharp Apr 09 '19 at 07:42
-
2Now you can also call [CustomElementRegistry.upgrade()](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/upgrade) yourself before `ce` is connected: `customElements.upgrade(ce)` – Qian Aug 22 '21 at 09:15