Introduction aux Custom Elements

Vous avez certainement perçu le vacarme qu'on fait autour des composants web et ce qu'ils vont apporter. Peter Gasston présente ici les éléments personnalisés, un petit guide pour mieux comprendre.

Par

Vous avez certainement entendu le bruit qu'on fait autour des composants web (web components) et de la façon dont ils vont changer le développement web à jamais.

Les composants web sont une suite de technologies connectées servant à rendre des éléments réutilisables sur le web. L'essentiel des discussions a tourné autour du DOM fantôme (shadow DOM), mais la technologie qui apportera sans doute le plus de transformations est ce qu'on appelle les custom elements (les éléments personnalisés), une méthode vous permettant de définir vos propres éléments, avec leurs comportements et propriétés.

Cette description est très ambigüe, l'objectif de cet article est donc d'expliquer à quoi servent les custom elements, ce qu'ils apportent de nouveau, et comment les utiliser. Notez que j'écrirai custom elements (nom commun) pour parler du concept et Custom Element (nom propre) pour parler de la technologie. Allons-y.

Les Custom Elements, pour quoi faire ?

L'idée de base est que si vous créez un élément jouant toujours le même rôle avec le même ensemble de propriétés et de fontions, vous devriez pouvoir lui donner un nom correspondant à ce qu'il fait. Nous avons l'élément video pour la vidéo, l'élément select pour afficher une boîte de sélection, l'élément img pour afficher des images, bref beaucoup d'éléments décrivent déjà leur fonction.

Mais le web actuel doit faire beaucoup plus qu'autrefois et HTML n'arrive pas toujours à suivre le changement. Les Customs Elements sont en passe de nous donner, à nous développeurs, la flexibilité requise pour créer des éléments selon leur fonction et l'accès à la définition de leurs propriétés.

Si les éléments que nous créons font sens, ils peuvent être intégrés à une future spécification HTML. Ce que nous faisons pourrait définir l'avenir de ce que nous faisons...

Ne peut-on déjà créer ces éléments ?

Vous avez raison, ami lecteur (fictif), nous le pouvons. C'est même trop facile. Ouvrez votre éditeur de texte favori, et dans un document html créez un élément comme suit :

<singes>...</singes>

Ouvrez le document dans votre navigateur, ça marche. Vous pouvez lui donner un style, lui attacher des événements JavaScript. Il n'est peut-être pas “valide” (mais qui se préoccupe encore de ça, fiston ?) mais il fonctionne. Vous pouvez réitérer l'expérience avec n'importe quel nom de balise, et ça créera un élément inline.

Oui, bon, bien sûr. Vous pourriez certainement faire tout cela, et peut-être même que ça rendrait votre code html plus compréhensible pour les autres, mais c'est bien le seul avantage. Les Custom Elements sont bien plus malins et ils apportent de vrais bénéfices mesurables. Nous allons les voir dans un instant. Mais d'abord, je voudrais vous montrer la facilité avec laquelle on peut les créer.

Les Custom Elements sont faciles à faire ?

Oui, je viens de vous le dire. La première étape consiste à trouver un nom adéquat. La seule règle à ce stade, afin d'éviter les clashes avec des éléments HTML actuels ou à venir, est d'utiliser un tiret quelque part dans le nom. Par exemple :

<grands-singes>...</grands-singes>

Une fois choisi le nom, l'étape suivante consiste à l'enregistrer dans le DOM, ce qui se fait en passant le nom comme argument de la méthode JavaScript registerElement() comme ceci :

document.registerElement('grands-singes');

À présent le DOM reconnaîtra votre élément nouvellement créé et on va pouvoir commencer à s'amuser. À propos, pour ajouter encore un peu de confusion à la terminologie, un élément créé de cette façon s'appelle un custom tag (attribut personnalisé), ne soyez pas surpris si j'emploie ce terme.

Oui mais... ça sert à quoi ?

Un peu de patience, ami lecteur. La grande différence entre ces gringalets de custom elements et les gros musclés de custom tags, c'est l'interface exposée au DOM. Les custom elements, non enregistrés et non reconnus, utilisent l'interface HTMLUnknownElement, alors que les custom tags, enregistrés et reconnus utilisent l'interface HTMLElement.

Quel différence ? Avec un HTMLElement, nous pouvons ajouter nos propres méthodes et propriétés, c'est à dire créer une API par élément. Attendez, je crois que je ne l'ai pas dit assez fort : une API par élément !! Oui, chaque custom tag peut avoir sa propre API.

Pour l'initier, on définit d'abord un nouveau prototype, puis on y attache des propriétés et des méthodes. Dans cet exemple, je crée une méthode appelée hoot() qui affiche un message dans la console :

var singeProto = Object.create(HTMLElement.prototype);
singeProto.hoot = function(){
    console.log("Les singes sont tes amis!");
}

Ensuite, il convient d'enregistrer l'élément, comme nous l'avons fait tout à l'heure, sauf que cette fois nous allons ajouter un argument dans les options de registerElement() pour indiquer qu'il devrait utiliser notre prototype nouvellement défini :

document.registerElement('grands-singes', {prototype: singeProto});

Une fois que c'est fait, vous pouvez accéder à votre élément dans le DOM et appeler la méthode :

var singes = document.querySelector('grands-singes');
singes.hoot();

C'est l'exemple le plus simple possible, mais prenez quelques instants pour imaginer comment il pourrait être étendu : en ajoutant des propriétés uniques, des attributs et des événements à chaque élément, en intégrant un balisage qui retourne un objet spécifique en fonction du contenu passé comme attribut, ou bien on pourrait même avoir des élément sans UI mais qui accomplissent des fonctions telles que des requêtes dans une base de données. Les opportunités sont immenses.

Un exemple rapide de l'utilité exceptionnelle des Custom Elements peut être démontré avec l'élément google-maps d'Eduardo Lundgren, qui embarque une Google Map et peut avoir des options passées comme valeurs d'attributs :

<google-maps latitude="-8.034881" longitude="-34.918377"></google-maps>

Les éléments existants peuvent être étendus ?

Wow, vous posez vraiment les bonnes questions. Oui, nous pouvons créer des Custom Elements qui étendent des éléments existants. Oui, nous pouvons créer une toute nouvelle API pour des éléments HTML existants ! Je sais, ça a l'air d'un délire de vieux fou et pourtant c'est vrai !

Par exemple, créons une table qui aurait notre méthode hoot(). Pour ce faire, nous suivons toutes les étapes précédemment décrites, puis nous ajoutons un nouvel argument dans les options de notre méthode registerElement(), genre :

document.registerElement('grands-singes', {
    prototype: singeProto,
    extends: 'table'
});

La valeur de l'argument extends informe le DOM que le custom element doit étendre l'élément table. Il nous faut maintenant indiquer au DOM que l'élément table veut être étendu, en utilisant l'attribut is :

<table is="grands-singes">…</table>

L'humble élément table peut maintenant avoir sa propre API. Par exemple, il pourrait aller chercher ses données dans une interface standardisée. Une table qui a une API pour aller chercher ses propres données !! Comment ne pas être bouleversé ?

Allons demander à Eduardo Lundgren un exemple réel d'élément étendu et regardons comment video-camera étend l'élément video pour utiliser un input live à partir de getUserMedia() :

<video is="video-camera"></video>

OK, cool. Quoi d'autre ?

Tout un ensemble d'événements utilisant les fonctions de rappel (callback, avec des noms brillamment prosaïques) sont déclenchés tout au long du cycle de vie des Custom Events (événements personnalisés) : Lorsqu'un élément est créé (createdCallback), attaché au DOM (attachedCallback) ou détaché du DOM (detachedCallback), ou lorsqu'un attribut est modifié (attributeChangedCallback). Par exemple, pour exécuter une fonction anonyme à chaque fois qu'une nouvelle instance de custom tag est créée dans une page, vous pourriez utiliser ceci :

singeProto.createdCallback = function () {…};

Comment les Custom Elements fonctionnent-ils avec les autres Web Components ?

Les Custom Elements ont été conçus pour être complètement interopérables avec les autres Web Components. Par exemple, vous pourriez inclure quelque chose dans un élément template, qui ne serait pas analysé par le navigateur avant que l'élément ne soit instancié.

<grands-singes>
    <template>...</template>
</grands-singes>

Vous pourriez vous assurer que le code interne est encapsulé et caché à l'utilisateur avec le DOM fantôme. Et le partage de vos éléments sur plusieurs fichiers et sites web serait la simplicité même grâce à HTML Imports.

Si ces technologies ne vous sont pas encore familières, pas d'inquiétude : les Custom Elements fonctionnent parfaitement sans elles.

Puis-je déjà utiliser les Custom Elements ?

Eh bien non... enfin, oui. Ce ne sont pas des concepts utopiques; les navigateurs y travaillent, les dernières versions de Chrome et Opera ont mis en oeuvre la méthode registerElement(), qui est également à l'essai sur Firefox Nightly. Mais les Custom Elements bruts ne sont pas encore prêts à être utilisés en production.

Une maman gorille serrant son petit dans ses bras
Les gorilles sont de grands singes... Bon, c'était soit ça, soit encore du JavaScript. (crédits: Marieke Ijsendoorn-Kuijpers)

Mais on peut contourner ce problème grâce aux Polymers. Si vous ne connaissez pas encore, il s'agit d'un projet communautaire ouvert destiné à permettre l'utilisation aujourd'hui des technologies du futur, ce qui comprend les Web Components et à travers eux les Custom Elements. Polymer est à la fois une bibliothèque de développement, qui utilise des implémentations natives lorsqu'elles sont disponibles et des polyfills lorsqu'elles ne le sont pas, et une bibliothèque UI comprenant des éléments habituels et des patterns construits avec ses propres technologies.

Si vous êtes intéressés par les Custom Elements - ce qui doit être le cas puisque vous êtes toujours là - alors Polymer est votre meilleur choix pour apprendre et réaliser.

Quid de l'accessibilité ?

Ah, ami lecteur fictif, là vous m'avez eu. L'utilisation des Custom Elements comporte une réserve de taille : JavaScript est requis. Sans lui, votre élément flambant neuf ne fonctionnera pas et retombera au niveau des HTMLUnknownElement. À moins que votre élément ne soit adopté nativement par les navigateurs, il n'y a pas de solution. Prévoyez donc une dégradation élégante, comme vous devriez d'ailleurs toujours le faire pour JavaScript.

Pour le reste, je vous suggère d'ajouter des rôles et des attributs ARIA à vos éléments pour vous assurer que tous les utilisateurs bénéficient d'une expérience de première-classe.

Et maintenant, je vais où ?

À la maison, reposez-vous. Si vous voulez poursuivre la lecture sur les Custom Elements, voici une liste de liens utiles :

(Photo du header par Kenny Louie / Flickr)


Ressources complémentaires en anglais

Ressources complémentaires en français

Les éléments personnalisés, traduction par Développez.com de l'article d'Eric Bidelman cité par Peter Gasston.


original paru le dans Smashing Magazine.

Sur l'auteur : est intégrateur web, développeur, écrivain, conférencier, auteur de The book of CSS3 et The Modern Web. Il blogge sur Broken Links et tweete. Il habite Londres.

Traduit avec l'aimable permission de Smashing Magazine et de l'auteur.
Copyright Smashing Magazine © 2014.