Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Elements data attributes not working

I am trying to make a custom html element and pass along with its instantiation some custom data tags. The problem is its dataset is always empty, and I can't figure out what I am doing wrong. I'm following the example from MDN on custom elements.. and this example does work in my browsers.. Additionally, I can successfully pass custom data tags when I add a standard img on my page, but not when I use my custom html element.

Below are my js file (defined in MyImage.js) and my html file. Along side these is an image called small.jpg.

class MyImage extends HTMLElement {
  constructor() {
    // Always call super first in constructor
    super();

    // Create a dom shadow root
    var domShadow = this.attachShadow({mode: 'open'});

    // Create a standard img element and set its attributes.
    var img = document.createElement('img');
    img.alt = this.dataset.name;
    img.src = this.dataset.img;
    
    // Add the image to the shadow root.
    domShadow.appendChild(img);
  }
}

// Define the new element
customElements.define('my-image', MyImage);
<html>
    <head>
        <title>myimage</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="MyImage.js"></script>
    </head>
    <body>
        <my-image data-name="My special image name" data-img="small.jpg"></my-image>
       
    </body>
</html>
like image 582
Jess the Mess Avatar asked Aug 05 '26 01:08

Jess the Mess


1 Answers

The snippet works if I change the location that the script is loaded. If I put the script element at the end of the body, the example works fine. See snippet below:

// Create a class for the element
class MyImage extends HTMLElement {
  constructor() {
    // Always call super first in constructor
    super();

    // Create a dom shadow root
    var domShadow = this.attachShadow({mode: 'open'});

    // Create a standard img element and set its attributes.
    var img = document.createElement('img');
    img.alt = this.dataset.name;
    img.src = this.dataset.img;


    // Add the image to the shadow root.
    domShadow.appendChild(img);
    
  }
}

// Define the new element
customElements.define('my-image', MyImage);
<html>
    <head>
        <title>myimage</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
    </head>
    <body>
        <my-image data-name="My special image name" data-img="small.jpg"></my-image>
       
        <script src="MyImage.js"></script>
    </body>
</html>

So now my question becomes: why? I know that the location of a script declaration/reference will affect when it's loaded in a page, but does anyone know exactly what is happening here that is causing it to not pass the custom attributes correctly when instantiating my custom element?

like image 101
Jess the Mess Avatar answered Aug 07 '26 16:08

Jess the Mess