Autonomous Custom Elements

Posted on  by admin
  • We can create custom HTML elements, described by our class, with its own methods and properties, events and so on.

Once a custom element is defined, we can use it on par with built-in HTML elements.

Internal vs. external styles

  1. That’s great, as HTML dictionary is rich, but not infinite.
  2. There are no , , … Just think of any other tag we might need.
  3. We can define them with a special class, and then use as if they were always a part of HTML.

Customized built-in elements

  1. There are two kinds of custom elements:.
  2. Autonomous custom elements – “all-new” elements, extending the abstract HTMLElement class.
  3. Customized built-in elements – extending built-in elements, like a customized button, based on HTMLButtonElement etc.

Creating an element which disables the ability to attach a shadow root

  1. First we’ll cover autonomous elements, and then move to customized built-in ones.
  2. To create a custom element, we need to tell the browser several details about it: how to show it, what to do when the element is added or removed to page, etc.
  3. That’s done by making a class with special methods.
  4. That’s easy, as there are only few methods, and all of them are optional.
  5. Here’s a sketch with the full list:.
  6. After that, we need to register the element:.
  7. Now for any HTML elements with tag , an instance of MyElement is created, and the aforementioned methods are called.

Autonomous custom elements

  1. We also can document.createElement('my-element') in JavaScript.
  2. Custom element name must have a hyphen -, e.g.
  3. my-element and super-button are valid names, but myelement is not.
  4. That’s to ensure that there are no name conflicts between built-in and custom HTML elements.
  5. For example, there already exists
  6. But it doesn’t do any formatting by itself.

Return value

  1. Let’s create element that displays the time in a nice, language-aware format:.
  2. The class has only one method connectedCallback() – the browser calls it when element is added to page (or when HTML parser detects it), and it uses the built-in Intl.DateTimeFormat data formatter, well-supported across the browsers, to show a nicely formatted time.
  3. We need to register our new element by customElements.define(tag, class).
  4. And then we can use it everywhere.
  5. If the browser encounters any elements before customElements.define, that’s not an error.

Rendering

  1. But the element is yet unknown, just like any non-standard tag.
  2. Such “undefined” elements can be styled with CSS selector :not(:defined).
  3. When customElement.define is called, they are “upgraded”: a new instance of TimeFormattedis created for each, and connectedCallback is called.
  4. They become :defined.
  5. To get the information about custom elements, there are methods:.

Upgrading Custom Elements

  1. customElements.get(name) – returns the class for a custom element with the given name,.
  2. customElements.whenDefined(name) – returns a promise that resolves (without value) when a custom element with the given name becomes defined.
  3. Rendering in connectedCallback, not in constructor.

Parameters

  1. In the example above, element content is rendered (created) in connectedCallback.

Autonomous custom element

  1. Why not in the constructor?
  2. The reason is simple: when constructor is called, it’s yet too early.

Exceptions

  1. The element is created, but the browser did not yet process/assign attributes at this stage: calls to getAttribute would return null.
  2. So we can’t really render there.

Chrome for Android

  1. Besides, if you think about it, that’s better performance-wise – to delay the work until it’s really needed.

Firefox for Android

  1. The connectedCallback triggers when the element is added to the document.

UC Browser for Android

  1. Not just appended to another element as a child, but actually becomes a part of the page.

Samsung Internet

  1. So we can build detached DOM, create elements and prepare them for later use.
  2. They will only be actually rendered when they make it into the page.
  3. In the current implementation of , after the element is rendered, further attribute changes don’t have any effect.
  4. That’s strange for an HTML element.

QQ Browser

  1. Usually, when we change an attribute, like a.href, we expect the change to be immediately visible.

Baidu Browser

  1. So let’s fix this.

KaiOS Browser

  1. We can observe attributes by providing their list in observedAttributes() static getter.
Resources:
IE Web Platform Status and Roadmap: Custom Elements
Firefox tracking bug: Implement Custom Elements (from Web Components)
Google Developers - Custom elements v1: reusable web components
customElements.define polyfill
WebKit Blog: Introducing Custom Elements