Orlok: Custom Elements

Beitrag lesen

Hallo Gunnar

Hm, meine sortierbare Tabelle funktioniert nicht […]

Du verwendest veraltete Syntax.

Zum Beispiel entspricht die Methode document.registerElement(), mit der du dein Custom Element bekanntmachst, nicht mehr dem aktuellen Stand der Spezifikation.


Die Registrierung von Custom Elements erfolgt heute über eine CustomElementRegistry genannte Schnittstelle, die über die Eigenschaft window.customElements angesprochen werden kann und die mehrere einschlägige Methoden bereitstellt.

// Create custom element

class SortableTable extends HTMLTableElement { /* ... */ }


// Register custom element

customElements.define('sortable-table', SortableTable, {
    extends: 'table'
});

Die Registrierung des Elements erfolgt wie in dem Beispiel oben mit der Methode define, die als erstes Argument den Namen des Elements erwartet (siehe hierzu die Produktion PotentialCustomElementName). Als zweites Argument wird der Konstruktor übergeben und optional als drittes ein Objekt, über dessen Eigenschaft extends ein Element bestimmt werden kann, das erweitert werden soll.

Die Definition von Custom Elements erfolgt mittels Klassensyntax. Browser die Custom Elements unterstützen, können damit etwas anfangen. Vielleicht könnte man hier auch mit der Methode Reflect.construct() etwas basteln, aber selbst wenn das ginge, wäre es unnötig umständlich.

// Create custom element

class SortableTable extends HTMLTableElement {
    constructor() {
        super();

        // do something
    }
}

Wie üblich kann die Pseudomethode constructor der Klasse weggelassen werden, wenn an dieser Stelle keine Anweisungen notiert werden sollen. Wird sie notiert, muss vor dem Zugriff auf die Instanz, also auf this, explizit super aufgerufen werden.

// Get constructor of custom element

SortableTable === customElements.get('sortable-table'); // true

Neben der Methode define gibt es auch noch eine Methode namens get, die den Namen eines Custom Elements erwartet und wenn vorhanden den dazugehörigen Konstruktor zurückgibt.

// Custom element definition using class expression

customElements.define(
    'my-element',
    class extends HTMLElement { /* ... */ }
);

Das ist zum Beispiel dann von Nutzen, wenn für die Erzeugung des Custom Elements wie in dem Beispiel oben ein Klassenausdruck und keine Deklaration verwendet wurde.

Schließlich gibt es noch eine Methode customElements.whenDefined(elementName), die ein Promise zurückgibt, das eingelöst wird wenn das Element erfolgreich registriert wurde.

// Important lifecycle callbacks

class MyElement extends HTMLElement {

    connectedCallback() {
        console.info('element is connected to DOM tree');
    }

    disconnectedCallback() {
        console.info('element was removed from DOM tree');
    }

}

Neben dem Konstruktor gibt es noch sogenannte Lifecycle Callbacks, also Funktionen, die bei bestimmten das Custom Element betreffenden Ereignissen aufgerufen werden. Die beiden wichtigsten sind oben notiert. connectedCallback wird aufgerufen, wenn das Element ins DOM gehängt wurde, und disconnectedCallback, wenn es aus dem DOM entfernt wurde.

class MyElement extends HTMLElement {

    static get observedAttributes() {
        return ['my-attribute'];
    }

    attributeChangedCallback(attributeName, oldValue, newValue) {
        if (attributeName === 'my-attribute') {

            // do something
        }
    }

}

Das Handling von Attributen des Elements erfolgt wie in dem Beispiel oben. Über den statischen Getter observedAttributes wird eine Liste der Attribute bereitgestellt, die überwacht werden sollen.

Wird ein Attribut gesetzt, dann wird die Methode attributeChangedCallback aufgerufen, der als erstes Argument der Name des geänderten Attributs und danach der alte und der neue Attributwert übergeben werden.

Vielleicht hilft dir das weiter.

Viele Grüße,

Orlok