Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Element class: this.getAttribute('data-*') returns null

I have copy & pasted to code from the Mozzila example https://developer.mozilla.org/en-US/docs/Web/Web_Components/Custom_Elements#Observed_attributes to files on my computer, and when i run it, i get null from every call to this.getAttribute. I see it working on the link above but when i run my copied project, it's null, the same is happening in another project i wrote, based on this example:

HTML file:

If nothing appeared below, then your browser does not support Custom Elements yet.
<x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"></x-product>
<x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"></x-product>
<x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"></x-product>

JS file:

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

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

    // Create a standard img element and set it's attributes.
    var img = document.createElement('img');
    img.alt = this.getAttribute('data-name');
    img.src = this.getAttribute('data-img');
    img.width = '150';
    img.height = '150';
    img.className = 'product-img';

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

    // Add an event listener to the image.
    img.addEventListener('click', () => {
      window.location = this.getAttribute('data-url');
    });

    // Create a link to the product.
    var link = document.createElement('a');
    link.innerText = this.getAttribute('data-name');
    link.href = this.getAttribute('data-url');
    link.className = 'product-name';

    // Add the link to the shadow root.
    shadow.appendChild(link);
  }
}

// Define the new element
customElements.define('x-product', XProduct);
like image 269
Amalin Avatar asked Mar 10 '17 13:03

Amalin


People also ask

Why is getAttribute returning NULL?

getAttribute() The getAttribute() method of the Element interface returns the value of a specified attribute on the element. If the given attribute does not exist, the value returned will either be null or "" (the empty string); see Non-existing attributes for details.

How do I create a custom element?

Customized built-in elements inherit from basic HTML elements. To create one of these, you have to specify which element they extend (as implied in the examples above), and they are used by writing out the basic element but specifying the name of the custom element in the is attribute (or property).

What is a custom element?

Custom elements allow web developers to define new HTML tags, extend existing ones, and create reusable web components. Aug 14, 2017 — Updated Sep 5, 2019.

How do custom elements work internally?

A custom element extends HTML by allowing you to define a tag whose content is created and controlled by JavaScript code. The browser maintains a CustomElementRegistry of defined custom elements, which maps an instantiable JavaScript class to an HTML tag.


1 Answers

You should use this.getAttribute() in the connectedCallback() method as attributes may be not defined yet when the constructor() method is called.

It's the case here where constructor() is called as soon as <x-product> is parsed, when its attributes are not attached yet.


Note that it could still work if you place the customElement.define() statement after the html code <x-product data-...>. This because the attributes are already attached to the <x-product> elements when the tag is defined as a Custom Element.

Look at this question for more details.

like image 105
Supersharp Avatar answered Sep 29 '22 12:09

Supersharp