Éléments personnalisés, DOM Shadow et NPM
Cet article se penche sur l'enrichissement du langage HTML avec des composants qui ont des fonctionnalités et des styles intégrés. Nous apprendrons également comment rendre ces éléments personnalisés réutilisables dans des projets utilisant NPM.
Même pour les composants les plus simples, le coût du travail humain peut avoir été important. Les équipes UX effectuent des tests d'utilisabilité. Un certain nombre de parties prenantes doivent signer la conception.
Les développeurs effectuent des tests AB, des audits d'accessibilité, des tests unitaires et des contrôles croisés par navigateur. Une fois que vous avez résolu un problème, vous ne voulez pas répéter cet effort . En construisant une bibliothèque de composants réutilisables (plutôt que de tout construire à partir de rien), nous pouvons continuellement utiliser les efforts passés et éviter de revisiter les problèmes de conception et de développement déjà résolus.
Création d'un composant Web
Définition d'un élément personnalisé
Il a toujours été possible de créer des noms de balises et d'afficher leur contenu sur la page.
Hello World!
HTML est conçu pour être tolérance de panne. Ce qui précède sera rendu, même si ce n'est pas un élément HTML valide. Il n'y a jamais eu de bonne raison de le faire – s'écarter des balises standardisées a traditionnellement été une mauvaise pratique. Cependant, en définissant une nouvelle balise à l'aide de l'API d'élément personnalisé, nous pouvons augmenter le HTML avec des éléments réutilisables dotés de fonctionnalités intégrées. Créer un élément personnalisé est très similaire à la création d'un composant dans React – mais ici s'étendaient HTMLElement
.
class ExpandableBox étend HTMLElement {
constructeur () {
super()
}
}
Un appel sans paramètre à super ()
doit être la première instruction du constructeur. Le constructeur doit être utilisé pour configurer les valeurs initiales d'état et par défaut et pour configurer les écouteurs d'événement. Un nouvel élément personnalisé doit être défini avec un nom pour sa balise HTML et la classe correspondante d'éléments:
customElements.define ('expandable-box', ExpandableBox)
C'est une convention pour mettre en majuscule les noms de classe. La syntaxe de la balise HTML est cependant plus qu'une convention. Et si les navigateurs voulaient implémenter un nouvel élément HTML et qu'ils voulaient l'appeler expandable-box? Pour éviter les conflits de noms, aucune nouvelle balise HTML standard ne comportera de tiret. En revanche, les noms des éléments personnalisés doivent comporter un tiret.
customElements.define ('any', Whatever) // invalid
customElements.define ('what-ever', Whatever) // valide
Cycle de vie des éléments personnalisés
L'API propose quatre réactions personnalisées – fonctions qui peuvent être définies dans la classe et qui seront automatiquement appelées en réponse à certains événements du cycle de vie d'un élément personnalisé. 19659005] connectedCallback est exécuté lorsque l'élément personnalisé est ajouté au DOM.
connectedCallback () {
console.log ("l'élément personnalisé est sur la page!")
}
Cela inclut l'ajout d'un élément avec Javascript:
document.body.appendChild (document.createElement ("expandable-box")) // "l'élément personnalisé est sur la page"
ainsi que élément dans la page avec une balise HTML:
// "élément personnalisé est sur la page"
Tout travail impliquant l'extraction de ressources ou le rendu doit être ici.
disconnectedCallback est exécuté lorsque l'élément personnalisé est supprimé du DOM.
disconnectedCallback () {
console.log ("l'élément a été supprimé")
}
document.querySelector ("expandable-box"). remove () // "l'élément a été supprimé"
adoptedCallback
est exécuté lorsque l'élément personnalisé est adopté dans un nouveau document. Vous n'avez probablement pas à vous soucier de celui-ci trop souvent.
attributeChangedCallback
est exécuté lorsqu'un attribut est ajouté, modifié ou supprimé. Il peut être utilisé pour écouter les modifications apportées aux attributs natifs standardisés comme désactivé ou src ainsi que tous les attributs personnalisés que nous inventons. C'est l'un des aspects les plus puissants des éléments personnalisés car il permet la création d'une API conviviale.
Attributs d'éléments personnalisés
Il existe de nombreux attributs HTML. Afin que le navigateur ne perd pas de temps à appeler notre attributeChangedCallback
quand n'importe quel attribut est modifié, nous devons fournir une liste des changements d'attributs que nous voulons écouter. Pour cet exemple, nous ne sommes intéressés que par un.
static get observedAttributes () {
retour ['expanded']
}
Donc maintenant notre attributeChangedCallback
ne sera appelé que lorsque nous changerons la valeur de l'attribut développé sur l'élément custom, car c'est le seul attribut que nous avons listé.
Les attributs HTML peuvent avoir des valeurs correspondantes (penser href, src, alt, valeur etc) alors que d'autres sont soit vrai soit faux (par exemple désactivé, sélectionné, requis ). Pour un attribut avec une valeur correspondante, nous inclurons ce qui suit dans la définition de la classe de l'élément personnalisé:
get yourCustomAttributeName () {
return this.getAttribute ('yourCustomAttributeName');
}
Définissez yourCustomAttributeName (nouvelleValeur) {
this.setAttribute ('yourCustomAttributeName', nouvelleValeur);
}
Pour notre exemple d'élément, l'attribut sera soit vrai soit faux, donc la définition du getter et du setter est un peu différente.
get expanded () {
return this.hasAttribute ('développé')
}
// le second argument de setAttribute est obligatoire, donc nous utiliserons une chaîne vide
set étendu (val) {
if (val) {
this.setAttribute ('expanded', '');
}
autre {
this.removeAttribute ('expanded')
}
}
Maintenant que le standard a été traité, nous pouvons utiliser attributeChangedCallback
.
attributeChangedCallback (name, oldval, newval) {
console.log (l'attribut `$ {name} a changé de $ {oldval} à $ {newval} !!`);
// fait quelque chose chaque fois que l'attribut change
}
Traditionnellement, la configuration d'un composant Javascript impliquait de passer des arguments à une fonction init
. En utilisant le attributeChangedCallback
il est possible de créer un élément personnalisé qui est configurable juste avec le balisage
Les DOM Shadow et les éléments personnalisés peuvent être utilisés séparément, et vous pouvez trouver des éléments personnalisés tout seuls. Contrairement à l'ombre DOM, ils peuvent être polyfilled. Cependant, les deux spécifications fonctionnent bien conjointement.
Attacher un balisage et des styles avec le DOM Shadow
Jusqu'à présent, nous avons traité le comportement d'un élément personnalisé. En ce qui concerne le balisage et les styles, cependant, notre élément personnalisé est équivalent à un non-vide vide . Pour encapsuler HTML et CSS dans le cadre du composant, nous devons joindre un DOM d'ombre. Il est préférable de le faire dans la fonction constructeur.
class FancyComponent extends HTMLElement {
constructeur () {
super()
var shadowRoot = this.attachShadow ({mode: 'ouvert'})
shadowRoot.innerHTML = ` bonjour monde!
`
}
Ne vous inquiétez pas de comprendre ce que signifie le mode – son standard, vous devez inclure, mais vous aurez toujours toujours vouloir ouvrir
. Cet exemple simple rendra simplement le texte "hello world". Comme la plupart des autres éléments HTML, un élément personnalisé peut avoir des enfants – mais pas par défaut. Jusqu'à présent, l'élément personnalisé ci-dessus que nous avons défini ne rendra aucun enfant à l'écran. Pour afficher du contenu entre les balises, nous devons utiliser un élément slot
.
shadowRoot.innerHTML = `
Bonjour tout le monde!
`
Nous pouvons utiliser une balise de style pour appliquer du code CSS au composant.
shadowRoot.innerHTML = bonjour monde!
du contenu par défaut `
Ces styles ne s'appliqueront qu'au composant, nous sommes donc libres d'utiliser des sélecteurs d'éléments sans que les styles n'affectent quoi que ce soit d'autre de la page. Cela simplifie l'écriture de CSS, rendant inutiles les conventions de dénomination comme BEM
Publication d'un composant sur NPM
Les paquetages NPM sont publiés via la ligne de commande. Ouvrez une fenêtre de terminal et déplacez-vous dans un répertoire que vous souhaitez transformer en un package réutilisable. Tapez ensuite les commandes suivantes dans le terminal:
- Si votre projet n'a pas encore de package.json
npm init
vous guidera dans la génération d'un. npm adduser
relie votre ordinateur à votre compte NPM. Si vous n'avez pas de compte préexistant, il en créera un nouveau.npm publish
Si tout va bien, vous avez maintenant avoir un composant dans le registre NPM, prêt à être installé et utilisé dans vos propres projets – et partagé avec le monde entier.
inclure des données dans les soumissions de formulaire . L'histoire de l'amélioration progressive n'est pas géniale. Traiter de l'accessibilité n'est pas aussi facile qu'il devrait être .
Bien qu'initialement annoncé en 2011, le support du navigateur n'est toujours pas universel. Le support de Firefox est attendu plus tard cette année. Néanmoins, certains sites internet de haut niveau (comme Youtube) en font déjà usage. Malgré leurs défauts actuels, universellement composants partageables ils sont l'option singulière et dans l'avenir nous pouvons nous attendre des ajouts passionnants à ce qu'ils ont à offrir.
Source link