tete du loic

 Loïc YON [KIUX]

  • Enseignant-chercheur
  • Référent Formation Continue
  • Responsable des contrats pros ingénieur
  • Référent entrepreneuriat
  • Responsable de la filière F2 ingénieur
  • Secouriste Sauveteur du Travail
mail
loic.yon@isima.fr
phone
(+33 / 0) 4 73 40 50 42
location_on
ISIMA
  • twitter
  • linkedin
  • viadeo

[JS] Baby Framework

Date de première publication : 2020/05/01

Cet exercice vise à introduire les éléments suivants :

Ce que l'on va faire marche sous Chrome et Firefox (en général, c'est ce dernier qui est le plus contraignant).

On cherche à faire une SPA ou single page application. L'application comportera trois pages. Voici le corps :

Les débuts


<page id="page1">
  <h1>Page 1</h1>
  <a href="#page2" >Vers la page 2</a>
</page>
<page id="page2">
  <h1>Page 2</h1>
  <a href="#page1" >Vers la page 1</a>
</page>
<page id="error">
  <h1>Page d'erreur</h1>
  <a href="#page1" >Retour à la page 1</a>
</page>

La balise <page> n'existe pas mais cela ne perturbe pas le navigateur.

Avec une pincée de CSS, chacune des pages occupe l'écran


:root {
  box-sizing    : border-box;
  overflow-x    : hidden;
} 

page {
    display     : block;
    width       : 100vw;
    min-height  : 100vh;
}

Avec une pincée de CSS, la page d'erreur que j'ai faite ressemble à cela :

On va ajouter un peu de javascript :


class App {
  _current;

  constructor() {
    this.hideAllPages();
  }

  hideAllPages() {
  }
}

var app = new App();

On vient de créer un classe App qui à l'instanciation cache toutes les pages sauf peut-être la première :-)

L'attribut _current est un attribut public. La convention d'écriture veut que l'on considère comme un attribut privé. Cette notion n'existe pas encore sous FF mais elle existe sous Chrome. Il faut alors nommer l'attribut #current

Nous allons ajouter un peu de routage maintenant. L'idée est de n'afficher qu'une seule page donnée dans l'adresse de la page


https://localhost/index.html#page2

Afficher la première page, c'est facile ! Comment afficher celle qui est donnée ? Il suffit d'analyser l'URL de la page et en particulier le champ hash d'un objet URL


new URL(document.location)

Pour le fun, on peut compter le nombre de pages uniquement avec le CSS

la propriété content devrait pourvoir s'appliquer à tout élément mais si cela ne marche pas utilisez uniquement ::before et ::after défini en CSS2.

Le mieux est d'utiliser l'identifiant de la page si elle en a un et d'en générer un dans le cas contraire, ce que l'on fera facilement dans la section suivate.

Balises personnalisées

La navigateur n'a pas été perturbé par la balise page mais ce n'est pas bon pour l'indexation. Nous allons donc utiliser la technique pour créer des composants web à savoir les éléments personnalisés ou CustomElements

Il y a une contrainte sur les noms d'éléments personnalisés, il faut que le nom contienne un tiret. Je propose de renommer la balise <page> en <simple-page> (il faut également mettre à jour le CSS éventuellement).

Il faut ensuite enregistrer l'élément :


customElements.define('simple-page', SimplePage);

Et créer la classe qui va bien :


class SimplePage extends HTMLElement  {
  constructor() {
    super();
  }
}

Il n'y a pas d'héritage "usuel" dans un langage à objet à prototype mais cette syntaxe permet de se raccrocher à ce que l'on a l'habitude de manipuler.

Cet élément, au titre de composant web va construire son propre arbre de donnée au sein d'un ShadowDOM où l'on mettra le code html, le style et autres ...


var shadow = this.attachShadow({mode: 'open'});

On modifiera le constructeur pour calculer un identifiant s'il n'est pas fourni ou afficher un message d'erreur avec la console ou la page d'erreur.

Compléments

La page d'erreur

Dans un framework, la page d'erreur est fondamentale pour tout ce qui pourrait mal se passer, l'erreur de routage étant probablement la plus fréquente

L'idée est de créer un page d'erreur à partir de simple-page avec un texte et style paramétré. On peut utiliser pour ce faire l'héritage pour faire une page d'erreur spécifique. Il y a deux possibilités avec l'une des syntaxes suivantes :


<error-page></error-page>
<simple-page is="error-page"></simple-page>

Si l'utilisateur ne définit pas de page d'erreur, il faut que l'application en crée un.

"display" d'une page

La page est pour l'instant affichée grâce à la propriété CSS display : block;

Si l'utilisateur choisit un autre mode d'affichage, il peut être intéressant de sauvegarder ce mode dans un attribut pour réafficher sereinement la page.

Pour ce faire, pour traiter "tous" les cas (et pas seulement le style donné en balise), il faut considérer le style "calculé".


let cs = window.getComputedStyle(element,null);
cs.getPropertyValue("display");

Autres

Typescript

L'idée maintenant est d'écrire le code de cette application, non plus en JS directement mais en Typescript. Pour cela, il faut sortir le code écrit en JS dans des fichiers externes et vous pouvez copier ces fichiers dans un sous-répertoire ts en modifiant l'extension (js devient ts).

Pour faire du TS, vous avez besoin du compilateur tsc qui s'installe avec npm (pour tous les utilisateurs de la machine)


npm install -g typescript

npm peut s'installer tout seul mais c'est le gestionnaire de paquet livré avec node.js

Pour transpiler "à la main", il faut exécuter la commande suivante :


tsc fichier.ts

La prochaine étape serait d'utiliser un outil pour transpiler automatiquement le typescript en javascript.