I try to get a html custom element to work:
When viewing the following example in the browser I must conclude that this.dataset.text
attribute in the constructor()
is:
<html>
<head>
<title>myimage</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div>
before custom element definition: <my-element data-text="Replaced and works as expected">Not Replaced</my-element>
</div>
<script>
class MyElement extends HTMLElement {
constructor() {
super();
this.text_attribute= this.dataset.text;
}
connectedCallback() {
if (this.text_attribute) {
this.innerText = this.text_attribute;
}
}
}
customElements.define('my-element', MyElement);
</script>
<div>
after custom element definition: <my-element data-text="Replaced">Not Replaced</my-element>
</div>
</body>
</html>
This seems to be a common behavior in chrome and Firefox. I can provide some more facts:
this.dataset.text
is always present in connectedCallback()
text
-attribut via this.getAttribute('data-text')
does behave in the same way as aboveCan anyone explain the purpose of this seemingly buggy behavior?
This isn't buggy behavior.
Your first <my-element>
is processed by the DOM parser before you define it.
Thus all attributes are known (in the DOM) when the constructor
executes.
In general you don't access DOM in the constructor
; as it also runs when you do:
let foo = document.createElement("my-element"); // absolutly no DOM created
Here is a trimmed down example:
<style>
my-element { display:block }
</style>
<my-element id="FOO"> ONE </my-element>
<script>
customElements.define('my-element', class extends HTMLElement {
constructor() {
super();
document.body.append(` ► constructor id:${this.id} ◄ `);
}
connectedCallback() {
document.body.append(` ► connected id:${this.id} ◄ `);
}
});
</script>
<my-element id="BAR"> TWO </my-element>
<my-element id="BAZ"> THREE </my-element>
NOTE
How FOO
innerHTML is written (because it was parsed) to the DOM before its constructor
runs
How BAR
and BAZ
constructor run before its innerHTML
is written to the DOM
and the id
value doesn't exist yet
I have seen many courses where they "save" you from this standard behavior by executing the <script>
async, thus after all DOM is parsed. They don't understand the technology...