Partie 1 : Découvrir Angular
Partie 2 : Acquérir les bases sur Angular
Partie 3 : Aller plus loin avec Angular
1 de 2

2. Les éléments personnalisés

Les éléments personnalisés permettent de créer des balises HTML personnalisées dans vos pages web, selon les besoins de votre application.

Vous vous demandez sûrement quel est l’intérêt de ces éléments personnalisés, étant donné que vous pouvez déjà mettre dans votre code une balise du type <balise-inventée>, et ensuite appliquer du JavaScript dessus, ou même du CSS :

<!-- Je crée une balise au hasard --> 
<une-balise-inventee></une-balise-inventee> 
<style> 
 /* Je rajoute un peu de style à ma nouvelle balise */ 
 une-balise-inventee { 
  width: 200px; 
  height: 50px; 
  border: 1px solid orange; 
 } 
</style> 
<script> 
 // Ce script permet d'afficher le nombre de balises personnalisées sur la page :
 var elementPerso = document.getElementsByTagName("une-balise-inventee"); 
 var quantite = elementPerso.length; 
 alert("Il y a " + quantite + " éléments <une-balise-inventee> dans ce document."); 
</script>

Alors je vous recommande tout de suite de ne jamais faire ça, et ce pour plusieurs raisons :

  • Votre code n’est pas valide, et développer du code invalide n’est pas très bien vu pour un développeur !
  • Si tout le monde faisait comme vous, il serait impossible de s’y retrouver : imaginez qu’une personne récupère votre code, et qu’à la place des balises <p>, <ul>, <h1>, … elle se retrouve face à des balises <une-balise-inventee>, <element-important>… cette personne ne saurait plus où donner de la tête ! Même si l’idée de créer ses propres balises peut être intéressante, vous êtes d’accord sur l’idée qu’il faut que tout le monde respecte les mêmes standards pour pouvoir s’y retrouver, non ?
  • Vous ne profitez pas des spécifications des Web Components : en respectant ces standards, vous pourriez profiter d’un coup d’un code valide, d’un standard respecté par tous les développeurs, et également des lifecycle callbacks. Bref, ça vaut le coup !

Heu, que signifie exactement ‘lifecycle callbacks’ ?

Il n’y a rien de compliqué ! Prenons un mot après l’autre :

  • Lifecycle  ou cycle de vie : désigne le fait que vos éléments personnalisés vont passer par plusieurs étapes au cours de leur existence (création, modification, suppression).
  • Callbacks : désigne simplement une fonction qui sera appelé lorsque votre élément passera par une des étapes de son cycle de vie.

Par exemple, vous pouvez attacher une fonction sur un de vos éléments, qui ne sera appelée que lorsque l’élément sera créé. Ainsi vous pouvez attacher des comportements à différentes étapes du cycle de vie d’un composant.

Il y a quatre lifecycle callback à avoir en tête si vous voulez vous en servir :

  1. createdCallback – Le comportement à définir quand l’élément est enregistré auprès du navigateur via Document.registerElement (Nous allons voir de quoi il s’agit ci-dessous).
  2. attachedCallback – La fonction qui est appelée quand l’élément est inséré dans le DOM.
  3. detachedCallback – La fonction qui est appelée quand l’élément est retiré du DOM.
  4. attributeChangedCallback – Le comportement de l’élément quand un de ses attributs est ajouté, modifié ou retiré.

Bon ok, tu m’as convaincu d’utiliser les standards du Web Component ! Mais comment on fait, tu ne nous as rien dit !

Alors, la clé pour utiliser les éléments personnalisés, c’est la méthode Document.registerElement. On utilise cette méthode pour enregistrer de nouveaux éléments, en lui passant le nom de notre élément ainsi qu’un tableau d’options, notamment un prototype pour notre nouvel élément. Ainsi le navigateur sait que l’élément que nous venons de lui déclarer est un élément personnalisé à part entière, et qu’il ne s’agit pas juste d’une balise malformée. En effet, si vous utilisez cette méthode, elle ajoutera à votre élément personnalisé l’interface HTMLElement. Cette interface représente n’importe quel élément HTML, ce qui signifie que votre code sera valide !

En revanche, si vous n’utilisez pas cette méthode et que vous faites votre élément personnalisé dans votre coin, alors votre code ne sera pas valide, et implémentera probablement l’interface HTMLUnknownElement !

Vous pouvez aussi construire votre propre élément personnalisé à partir d’un élément natif. Prenons <button> par exemple. Alors vous ne pourrez pas utiliser un nom personnalisé comme <my-button>, vous devrez utiliser une syntaxe comme <button is=’my-button’>.

Bon je sens que vous êtes impatient de voir du code, et d’arrêter de m’écouter parler tout seul !

Rassurez-vous, voici un exemple de qualité pour me rattraper. Nous allons créer un petit élément personnalisé pour afficher la vignette et quelques informations sur des super-héros.

Créons tout de suite un élément personnalisé nommé <super-heros>. Pour cela nous avons besoin d’un nom et d’un prototype. C’est parti !

Faites attention, le nom de votre élément personnalisé doit contenir un tiret pour indiquer au navigateur qu’il ne s’agit pas d’un élément natif. Généralement on préfixe notre élément par un diminutif du nom de notre application, comme : ‘monApp-monElement’.

Vous devez également associer un template à votre élément, sinon le navigateur ne saura pas ce qu’il doit afficher.

Créer donc une page index.html avec le code suivant :

<!doctype html> 
<html> 
 <head> 
  <meta charset="UTF-8"> 
  <title>Test</title> 
 </head> 
 <body> 
  <script>
   // On crée une classe pour notre élément personnalisé,
   // et on lui ajoute un template avec la méthode ‘innerHTML’.
   class SuperHero extends HTMLElement {
    constructor() {
     super();
     this.innerHTML = '<h1>Superman</h1>';
    }
   }

   // On définit notre élément personnalisé avec la méthode 'define'.
   customElements.define('super-hero', SuperHero); 
   // On ajoute notre élément sur la page web !
   document.body.appendChild(new SuperHero());
  </script> 
 </body> 
</html>

Affichez ensuite cette page dans votre navigateur préféré : vous verrez affiché Superman en titre sur votre page !

Si vous inspectez votre code, vous verrez que le DOM de votre page contient notre nouvelle balise :

La console du navigateur lorsque j’inspecte mon titre « Superman ».

Pour vous prouver que notre code est bien valide, essayez de faire valider cette page HTML par le W3C Validator (en copiant et collant le code ci-dessus), vous obtiendrez alors ce magnifique message :

Notre code est valide, en voici la preuve ! 😎

Vous voyez bien que nous ne sommes pas fous, nous avons bien créé une nouvelle balise HTML valide !

Qu’attendons-nous pour conquérir le monde !?!

Oui mais on aurait pu faire ça avec <h1>Superman</h1>, non ?

Ah, la question qui fâche ! Bon, oui, sur la forme vous avez raison, mais vous auriez perdu les avantages des éléments personnalisés :

  • Réutilisabilité : Maintenant que nous avons défini notre élément personnalisé, nous pouvons le réutiliser autant de fois que vous le voulez. Imaginons que vous ayez développé un élément permettant d’afficher la présentation d’un héros, et bien il vous suffit d’appeler cet élément autant de fois que vous avez de héros !
  • Personnalisation : Je ne vous l’ai pas encore montré, mais nous pouvons ajouter des propriétés et des méthodes personnalisées encapsulées dans notre élément, ce que nous ne pouvons pas faire avec une simple balise.
  • Encapsulation : Tout le code que nous développons au sein de notre élément peut être encapsulé dedans, et ainsi nous pouvons développer nos pages HTML comme un assemblage d’éléments personnalisés !

Attend, tu viens de dire que l’on peut encapsuler notre code HTML, avec le code Javascript et CSS associés, mais comment éviter les conflits entre les éléments alors ?

En effet, que-ce passe-t-il si vous avez sur votre page un élément A qui indique que tous ces paragraphes doivent être écrit en jaune, et un élément B qui spécifie que tous les paragraphes doivent être écrit en rouge ? Lequel l’emporte ? Et que deviennent les paragraphes qui n’appartiennent à aucun élément, et qui sont simplement présents sur la page ?

Je vous rassure, la spécification des composants Web prend en compte ce genre de problématique, et c’est pour ça qu’on va tout de suite voir ce qu’est le DOM de l’ombre. Il permettra d’éviter les conflits entre les éléments personnalisés.

Pour rappel, les éléments personnalisés que nous venons de voir sont un des quatre standards des composant web, mais vous pouvez tout à fait les utiliser pour eux-mêmes, indépendamment des composants web.