TL;DR;
Dans le dernier article, je vous présentais les composants web. Une des API permettant de créer des composants est l’API html5 Custom Element. Elle permet de déclarer un nouveau composant dans le DOM et que celui soit reconnu par le browser pour l’affichage et avec ses comportements spécifiques.
Depuis cet article, la spec à changé et ne colle plus à la description ci-dessous. Référez-vous plutôt à la spec V1 décrite ici : https://developers.google.com/web/fundamentals/web-components/
Introduction
La notion d’élément personnalisé (Custom Element) est le fait de pouvoir créer nos propres balises, sans qu’elles soient ignorées par le navigateur. Pour cela, nous utilisons le JavaScript afin de déclarer notre composant.
Restriction
La seule restriction est que le nom de notre élément perso doit contenir un tiret – . Ceci permettra de ne pas écraser des éléments natifs à la manière de namespace.
Exemple valide : <my-element>
Exemple invalide : <element>
Création d’un élément personnalisé
La Class ou le prototype
La création de notre composant passe tout d’abord par la création d’un prototype JavaScript représentant le composant et héritant soit du prototype d’une balise HTML, soit du protoype d’un autre composant existant à étendre.
Pour la balise HTML ce sera donc HTMLElement , et pour un composant spécifique cela dépendra du composant, comme par exemple pour un input on étendra HTMLInputElement .
En ES6, ce prototype sera définit à l’aide d’une class et de l’héritage à l’aide du mot clé extends .
Ex: class MyElement extends HTMLElement
Les propriétés et méthodes de prototype
Le contenu du prototype correspondra à toutes les propriétés et méthodes qui lui seront utiles. Mais également 4 méthodes qui concernent les différents événements qui interviendront dans son cycle de vie et que voici :
- createdCallback() : Méthode exécutée lorsque le composant a été créé et sa définition enregistrée
- attachedCallback() : Méthode exécutée lorsque l’élément a été inséré dans le DOM
- detachedCallback() : Méthode exécutée lorsque l’élément est retiré du DOM
- attributeChangedCallback(attrName, oldValue, newValue) :Méthode exécutée lorsqu’un attribut de l’élément a été modifié.
L’enregistrement de l’élément
Une fois la class créée, il ne reste plus qu’à l’enregistrer dans l’annuaire des éléments DOM reconnu par le navigateur afin qu’elle soit utilisable. Pour cela, on utilisera la méthode document.registerElement(elementName, prototype, options) .
Cette méthode reçoit les paramètres suivants:
- elementName (string) est une chaine de caractère qui correspond au nom de la balise qui sera utilisée pour notre composant. Ex: on passera ‘my-button’ , si notre composant sera créé avec la balise <my-button> .
- prototype (object) est la class prototype définie.
- options (object) est un objet supplémentaire qui contiendra par exemple l’attribut prototype de l’élément étendu si on veut étendre un élément existant comme par exemple un input.
Ex: { prototype: HTMLInputElement }
Le styling
Tant que le custom element ne contient pas de Shadow DOM, ses différentes parties peuvent être stylisée comme on le fait habituellement. Pour le style du Shadow DOM, il faudra utiliser des sélecteurs spécifiques qui sont expliqués dans l’article du même nom.
Il y’a quand même un nouveau sélecteur qui permet de cibler un état non reconnu d’un custom élément, le sélecteur :unresolved . Celui-ci nous permet d’afficher un style temporaire tant que la balise n’est pas transformée en composant. Voici un exemple d’utilisation :
my-element:unresolved { opacity: 0; } my-element:unresolved::before { content: 'Loading component'; }
Exemple complet
Voici un exemple de tout le processus de déclaration de custom components :
Support navigateur
Le support actuel de cette API se trouve ici : http://caniuse.com/#feat=custom-elements