Web Components : diapos de cours
Transcription
Web Components : diapos de cours
Web Components Jean-Marc Lecarpentier GREYC - Université de Caen Web Components • Ensemble de 4 spécifications • Custom Elements • Shadow DOM • Templates • HTML imports Custom Elements • Définir des éléments personnalisés • Encapsuler dans une seule balise : • un ensemble d’éléments HTML • leurs interactions Javascript • leur mise en forme CSS Shadow DOM • Définir des mécanismes pour éviter les collisions en ayant plusieurs DOM dans une page • Encapsulation des custom elements • Frontière avec le DOM du document • CSS et requêtes DOM sont séparées Templates • Permettre d’avoir des squelettes HTML • Templates remplis avec Javascript • Utile pour la structure de certains custom elements HTML imports • Avoir un moyen d’importer les custom elements • Balise <link> de type import • Gestion des dépendances et de l’ordre d’import Custom Elements • Créer des éléments HTML/DOM • Pouvant dériver d’autres éléments • Ayant leur propre API • Encapsulés dans un package • Élément doit être déclaré : document.registerElement('mon-element', { options }); • options est un objet décrivant le prototype de l’élément • Balise doit contenir un tiret et être en minuscules Dérivation • Possibilité de dériver d’un élément HTML • Spécifier le type et la dérivation lors de la déclaration : var monBouton = document.registerElement('mon-bouton', { prototype: Object.create(HTMLButtonElement.prototype), extends: 'button' }); <button is="mon-bouton" disabled onclick="alert('cliqué')">Un bouton mon-bouton</button> • Possibilité de dériver d’un custom element Propriétés et méthodes • Définir le prototype de l’élément en conséquence var monProto = Object.create(HTMLElement.prototype); monProto.maMethode = function() { alert('mon-proto a activé maMethode()'); } // ajouter une propriété non modifiable Object.defineProperty(monProto, 'maPropriete', { value: 'la valeur de maPropriete'}); document.registerElement('mon-proto', monProto); Lifecycle callbacks • createdCallback : une instance est créée • attachedCallback : une instance est insérée dans le document • detachedCallback : une instance est supprimée du document • attributeChangedCallback(attribut, oldVal, newVal) : un attribut a été ajouté, supprimé ou modifié Ajouter du contenu • Dynamiquement avec createdCallback • Problématique : les éléments constituants le custom element doivent être indépendants du reste de la page • Shadow DOM : mécanismes d’encapsulation Shadow DOM • Encapsuler des éléments et leur contenu • Éviter d’être pollué par la CSS et les interactions du document • Document tree • Tout élément peut être Shadow host • Shadow host contient shadow root • Séparation complète entre host et root ⟹ pas de relation parent/child DOM ⟹ pas de sélection CSS • Exemple : widget avec ses interactions et son style Shadow tree • Encapsule son contenu • N’affiche que ce qu’il veut • Créer un Shadow tree : var host = document.querySelector('.mon-widget'); var root = host.createShadowRoot(); root.textContent = 'Je suis le contenu du shadow tree’; • Console Chrome : Templates et Shadow DOM • Prendre le contenu du Shadow host • Pour le mettre dans le Shadow tree • Mis en forme selon un template HTML template • Élément <template> • Inerte et absent du DOM tant que non activé ⟹ images, videos, etc chargées lors de l’activation • Activation en Javascript. • Propriété content pour accéder au contenu du template <template id="template"> <h1>un exemple de template</h1> </template> var template = document.getElementById(‘template'); document.body.appendChild(document.importNode(template.content, true)); Exemple Javascript : • var host = document.querySelector('.mon-widget'); var root = host.createShadowRoot(); var template = document.getElementById('template'); root.appendChild(document.importNode(template.content, true)); HTML : • <div class="mon-widget"> <h1>Mon Widget n°1</h1> <p>Du contenu de widget</p> </div> <template id="template"> <style> h1 { color: #aaaaaa; } </style> <h1>le titre de mon widget dans le shadow tree</h1> <content select="h1"></content> </template> Shadow tree et CSS • CSS Scoping module • Pseudo classes :host et :host-context • Pseudo éléments ::shadow et ::content • Sélecteur /deep/ • Tutoriel : http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/ • Draft W3C : https://drafts.csswg.org/css-scoping/ Shadow tree et évènements • Évènements traversent ou non la frontière • Ceux qui traversent sont modifiés pour conserver l’encapsulation • Évènement réassigné pour sembler provenir du shadow host • Javascript event.path pour voir le chemin HTML imports • Charger des ressources sans <iframe>, Ajax, etc • <link rel="import" href=“/chemin/du/fichier.html”> • Utiliser CORS si import d’un autre domaine • Évènements load et error • Document importé disponible via son DOM Document importé • Notion de import document • <link> CSS du import non utilisées dans document principal, sauf CSS dans élément <style> • Propriété import de l’élément link : var importDOM = document.querySelector(‘link[rel=“import"]').import; • Javascript de l’import exécuté dans le contexte window • Accès au document principal par l’objet document Imports et Custom Elements • Importer un document définissant ses éléments • L’import exécute les scripts ⟹ document.registerElement est exécuté • Éléments ainsi créés utilisables dans le document Imports multiples • Import peut importer ses propres ressources • Gestion des dépendances et de l’ordre des imports • Ressources importées une seule fois même si incluses dans divers imports • Scripts exécutés une seule fois ⟹ fonctionne même si un script est importé n fois Imports et affichage • <link rel=“import”> bloque l’affichage de la page • De même que <link rel=“stylesheet”> • Éviter l’effet FOUC • Être certain d’avoir les custom elements déclarés • Considérer les performances http://www.html5rocks.com/en/tutorials/webcomponents/imports/#depssubimports Web Components • Templates • Custom Elements • Shadow DOM • HTML imports • Ensemble intéressant • Utilisable avec polyfill https://github.com/WebComponents/webcomponentsjs