Skip to content
This repository has been archived by the owner on Jul 26, 2022. It is now read-only.

Content Changes

Jan Miksovsky edited this page Sep 30, 2020 · 10 revisions

Checklist » Content

✓ Content Changes

Will the component respond to runtime changes in its content (including reprojected content)?

Many components perform processing of their children: to lay them out, extract data from them, set styles on them, etc. Take care to perform such processing:

  1. When the component is first initialized, and
  2. Whenever the component content (including distributed content) changes.

This component counts its children, but as written only supports #1 above:

class CountingElement extends HTMLElement {

  constructor() {
    super();
    const root = this.attachShadow({ mode: 'open' });
    root.innerHTML = `<slot></slot>`;
  }

  connectedCallback() {
    // Count the component's children
    // Not good enough! Only runs when first attached.
    this.count = this.children.length;
  }

}

This is insufficient, because the same processing needs to also apply when the component's contents are changed at runtime. Even if you envision your component's users typically defining content up front in static HTML, it's highly likely that someone will want to manipulate the component's content dynamically. Moreover, changes need in [distributed content](Content Distribution) should also trigger such processing.

Monitoring content changes with slotchange events

The <slot> element supports a slotchange event that is invoked whenever the nodes distributed to that slot change. By listening to this event, your component can handle not only initial content, but any changes to the content:

class CountingElement extends HTMLElement {

  constructor() {
    super();
    const root = this.attachShadow({ mode: 'open' });
    const slot = document.createElement('slot');
    root.appendChild(slot);
    slot.addEventListener('slotchange', event => this.countChildren());
  }

  connectedCallback() {
    this.countChildren();
  }

  /* Count the component's children */
  countChildren() {
    this.count = this.children.length;
  }

}
Clone this wiki locally