Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

137
Views
Attributes in custom element constructor missing dependent on script tag location

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:

  • present before the script defining the custom element
  • empty after the script defining the custom element

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

  • the this.dataset.text is always present in connectedCallback()
  • accessing the text-attribut via this.getAttribute('data-text') does behave in the same way as above

Can anyone explain the purpose of this seemingly buggy behavior?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

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

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!