Polimero - Shadow DOM e Styling

Shadow DOM è una nuova proprietà del DOM utilizzata per i componenti di costruzione.

Example

Nel codice seguente, il componente di intestazione include il titolo della pagina e il pulsante del menu.

<header-demo>
   <header>
      <h1>
         <button>

Shadow DOM consente di individuare i figli in una sottostruttura con ambito, nota come shadow tree.

<header-demo>
   #shadow-root
   <header>
      <h1>
      <button>

La radice shadow-root è chiamata come la parte superiore dell'albero shadow e l'elemento che è collegato all'albero è chiamato shadow host (header-demo). Questo host shadow include una proprietà chiamata shadowRoot, che specifica la radice shadow. La radice shadow identifica l'elemento host utilizzando una proprietà host.

Shadow DOM e composizione

L'albero delle ombre può essere reso al posto dei figli dell'elemento, se c'è un elemento nel DOM ombra. I figli dell'elemento possono essere visualizzati aggiungendo l'elemento <slot> all'albero delle ombre.

Ad esempio, usa il seguente albero delle ombre per <header-demo>.

<header>
   <h1><slot></slot></h1>
   &ltbutton>Menu</button>
</header>

Aggiungi i figli all'elemento <my-header> come -

<header-demo>Shadow DOM</header-demo>

L'intestazione sostituisce l'elemento </slot> con i figli specificati sopra come -

<header-demo>
   <header>
      <h1>Shadow DOM</h1>
      <button>Menu</button>
   </header>
</header-demo>

Contenuto di riserva

Il contenuto di fallback può essere visualizzato quando non ci sono nodi assegnati allo slot. Ad esempio:

<my-element>
   #shadow-root
   <slot id = "myimgicon">
      <img src = "img-demo.png">
   </slot>
   <slot></slot>
<my-element>

Puoi fornire la tua icona per un elemento come:

<my-element>
   <img slot = "myimgicon" src = "warning.png">
<my-element>

Distribuzione multilivello

Puoi allocare l'elemento slot a uno slot, noto come distribuzione multilivello.

Ad esempio, prendi due livelli di un albero delle ombre come mostrato di seguito:

<parent-element>
   #shadow-root
      <child-element>
      <!-- display the light DOM children of parent-element inside child-element -->
      <slot id = "parent-slot">
	  
   <child-element>
      #shadow-root
         <div>
            <!-- Render the light DOM children inside div by using child-element -->
            <slot id = "child-slot">

Considera il codice seguente:

<parent-element>
   <p>This is light DOM</p>
<parent-element>

La struttura di un albero appiattito è simile alla seguente.

<parent-element>
   <child-element>
      <div>
         <slot id = "child-slot">
            <slot id = "parent-slot">
               <p>This is light DOM</p>

Shadow DOM utilizza le seguenti API di slot per il controllo della distribuzione:

  • HTMLElement.assignedSlot - Alloca lo slot per un elemento e restituisce null, se non c'è allocazione di un elemento a uno slot.

  • HTMLSlotElement.assignedNodes - Fornisce l'elenco dei nodi insieme allo slot e restituisce i nodi distribuiti, quando si imposta l'opzione flatten su true.

  • HTMLSlotElement.slotchange - Questo evento si attiva quando ci sono modifiche nei nodi distribuiti dello slot.

Retargeting di eventi

Specifica l'obiettivo dell'evento in cui l'elemento può essere rappresentato nello stesso ambito dell'elemento in ascolto. Fornisce un evento da un elemento personalizzato, che sembra provenire dal tag dell'elemento personalizzato, al contrario di un elemento all'interno.

Example

L'esempio seguente mostra l'uso del retargeting di eventi nel file Polymer.js. Crea un file chiamato index.html e inserisci il codice seguente.

<!doctype html>
<html>
   <head>
      <title>Polymer Example</title>
      <script src = "bower_components/webcomponentsjs/webcomponents-lite.js"></script>
      <link rel = "import" href = "bower_components/polymer/polymer.html">
      <link rel = "import" href = "retarget-event.html">
   </head>
   
   <body>
      <template id = "myapp" is = "dom-bind">
         <retarget-event on-tap = "clicky"></retarget-event>
      </template>
      
      <script>
         var myval = document.querySelector('#myapp');
         myval.clicky = function(e) {
            console.log("The retargeted result:", Polymer.dom(myval));
            console.log("Normal result:", e);
         };
      </script>
   </body>
</html>

Ora, crea un altro file chiamato retarget-event.html e includi il codice seguente.

<link rel = "import" href = "bower_components/polymer/polymer-element.html">

//it specifies the start of an element's local DOM
<dom-module id = "retarget-event">

   <template>
      <span>Click on this text to see result in console...</span>
   </template>

   <script>
      Polymer ({
         is: 'retarget-event',
      });
   </script>
</dom-module>

Output

Per eseguire l'applicazione, accedere alla directory del progetto creato ed eseguire il comando seguente.

polymer serve

Ora apri il browser e vai a http://127.0.0.1:8081/. Di seguito sarà l'output.

Fare clic sul testo sopra e aprire la console per visualizzare un evento con retargeting come mostrato nella schermata seguente.

Styling DOM ombra

È possibile applicare uno stile al DOM ombra utilizzando le proprietà di stile, che ereditano dall'host all'albero ombra.

Example

<style>
   .mydemo { background-color: grey; }
</style>

<my-element>
#shadow-root
   <style>
      //this div will have blue background color
      div { background-color: orange; }
   </style>
   <div class = "mydemo">Demo</div>

Templating DOM

La sottostruttura DOM può essere creata per un elemento utilizzando il modello DOM. Puoi creare la radice ombra per l'elemento e copiare il modello in un albero ombra aggiungendo un modello DOM a un elemento.

Il modello DOM può essere specificato in due modi:

  • Crea un elemento <dom-module>, che dovrebbe corrispondere al nome di un elemento insieme a un attributo id.

  • Definisci un elemento <template> all'interno di <dom-module>.

Example

<dom-module id = "my-template">
   <template>I am in my template!!!</template>

   <script>
      class MyTemplate extends Polymer.Element {
         static get is() { return  'my-template' }
      }
      customElements.define(MyTemplate.is, MyTemplate);
   </script>
</dom-module>

Definisci lo Shadow DOM di un elemento

Shadow DOM consente di definire lo stile degli elementi personalizzati utilizzando proprietà di stile come caratteri, colori del testo e classi, senza applicarlo al di fuori dell'ambito del tuo elemento.

Assegniamo uno stile all'elemento host usando il :hostselettore (un elemento collegato al DOM ombra viene chiamato come host). Crea un file chiamato polymer-app.html e aggiungi il seguente codice al suo interno.

<link rel = "import" href = "../../bower_components/polymer/polymer-element.html">

<dom-module id = "polymer-app">
   <template>
      <style>
         :host {
            color:#33ACC9;
         }
      </style>
      <h2>Hello...[[myval]]!</h2>	
  </template>

  <script>
      class PolymerApp extends Polymer.Element {
         static get is() { return 'polymer-app'; }
         static get properties() {
            return {
               myval: {
                  type: String, value: 'Welcome to Tutorialspoint!!!'
               }
            };
         }
      }

      window.customElements.define(PolymerApp.is, PolymerApp);
   </script>
</dom-module>

Esegui l'applicazione come mostrato nel capitolo precedente e vai ahttp://127.0.0.1:8000/. Di seguito sarà l'output.

Contenuto con slot di stile

È possibile creare slots nel modello di un elemento, che sono occupati in fase di esecuzione.

Example

L'esempio seguente illustra l'uso del contenuto a slot nel modello dell'elemento. Crea un file index.html e aggiungi il seguente codice al suo interno.

<!doctype html>
<html>
   <head>
      <title>Polymer Example</title>
      <link rel = "import" href = "bower_components/polymer/polymer.html">
      <link rel = "import" href = "slotted-content.html">
   </head>
   
   <body>
      <slotted-content>
         <div slot = "text">This is Polymer.JS Slotted Content Example</div>
      </slotted-content> 
   </body>
</html>

Ora crea un altro file chiamato slotted-content.html e includi il codice seguente.

<link rel = "import" href = "bower_components/polymer/polymer-element.html">

<dom-module id = "slotted-content">
   <template>
      <style>
         ::slotted(*) {
            font-family: sans-serif;
            color:#E94A9D;
         }
      </style>
      
      <h2>Hello...[[prop1]]</h2>
      <h3>
         <div><slot name='text'></slot></div>
      </h3>
   </template>
   
   <script>
      Polymer ({
         is: 'slotted-content', properties: {
            prop1: {
               type: String,
               value: 'Welcome to Tutorialspoint!!',
            },
         },
      });
   </script>
</dom-module>

Eseguire l'applicazione come mostrato nell'esempio precedente e passare a http://127.0.0.1:8081/. Di seguito sarà l'output.

Utilizzo dei moduli di stile

Puoi condividere gli stili tra gli elementi insieme ai moduli di stile. Specifica gli stili nel modulo di stile e condividili tra gli elementi.

Example

L'esempio seguente mostra come utilizzare il modulo di stile tra gli elementi. Crea un file index.html e aggiungi il seguente codice al suo interno.

<!doctype html>
<html>
   <head>
      <title>Polymer Example</title>
      <link rel = "import" href = "bower_components/polymer/polymer.html">
      <link rel = "import" href = "style-module.html">
   </head>
   
   <body>
      <style-module></style-module> 
   </body>
</html>

Crea un altro file chiamato style-module.html con il codice seguente.

<link rel = "import" href = "bower_components/polymer/polymer-element.html">

<dom-module id = "style-module">
   <template>
      <!-- here, including the imported styles from colors-module page -->
      <style include="colors-module"></style>
      <style>
         :host {
            font-family: sans-serif;
            color: green;    
         }
      </style>
      
      <h2>Hello...[[prop1]]</h2>
      <p class = "color1">Sharing styles with style modules 1...</p>
      <p class = "color2">Sharing styles with style modules 2...</p>
      <p class = "color3">Sharing styles with style modules 3...</p>
   </template>
   
   <script>
      Polymer ({
         is: 'style-module', properties: {
            prop1: {
               type: String, value: 'Welcome to Tutorialspoint!!',
            },
         },
      });
   </script>
</dom-module>

Ora, crea un altro file chiamato colors-module.html , che fornisce i moduli di stile agli elementi come mostrato nel codice seguente.

<link rel = "import" href = "bower_components/polymer/polymer-element.html">

<dom-module id = 'colors-module'>
   <template>
      <style>
         p.color1 {
            color: #EA5AA5;
         }
         p.color2 {
            color: #4B61EA;
         }
         p.color3 {
            color: #D3AA0A;
         }
      </style>
   </template>
</dom-module>

Esegui l'applicazione e vai a http://127.0.0.1:8081/. Di seguito sarà l'output.

Usa proprietà personalizzate

Le proprietà CSS personalizzate possono essere utilizzate per definire l'aspetto dell'elemento nella tua applicazione utilizzando l'elemento Polymer. Le proprietà personalizzate forniscono variabili CSS a cascata, che possono essere utilizzate al di fuori dell'ambiente di elementi personalizzati che evitano la dispersione dei dati di stile in un foglio di stile.

Le proprietà personalizzate possono essere definite in modo simile alle proprietà CSS standard, che ereditano dall'albero DOM composto. Nell'esempio precedente, puoi vedere le proprietà CSS personalizzate definite per gli elementi.

Sotto l'ereditarietà CSS, se non è stato definito uno stile per un elemento, erediterà lo stile dal suo genitore come mostrato nel codice seguente.

<link rel = "import" href = "components/polymer/myelement-style.html">
<myelement-style>
   <style is = "myelement-style">
      p {
         color: var(--paper-red-900);
      }
      paper-checkbox {
         --paper-checkbox-checked-color: var(--paper-red-900);
      }
   </style>
</myelement-style>

<body>
   <p><paper-checkbox>Check Here</paper-checkbox></p>
</body>