Polymer - Shadow DOM 和樣式



Shadow DOM 是 DOM 的一個新特性,用於構建元件。

示例

在以下程式碼中,header 元件包含頁面標題和選單按鈕。

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

Shadow DOM 允許在稱為**陰影樹**的作用域子樹中定位子元素。

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

陰影根被稱為陰影樹的頂部,附加到樹的元素稱為陰影宿主 (header-demo)。此陰影宿主包含一個名為 shadowRoot 的屬性,該屬性指定陰影根。陰影根使用 host 屬性標識宿主元素。

Shadow DOM 和組合

如果 Shadow DOM 中存在元素,則可以渲染陰影樹而不是元素的子元素。可以透過將<slot> 元素新增到陰影樹來渲染元素的子元素。

例如,對<header-demo> 使用以下陰影樹。

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

將子元素新增到<my-header> 元素中,如下所示:

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

header 將上述指定的子元素替換為</slot> 元素,如下所示:

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

回退內容

當沒有節點分配到插槽時,可以顯示回退內容。例如:

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

您可以為元素提供您自己的圖示,如下所示:

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

多級分發

您可以將插槽元素分配到一個插槽,這被稱為多級分發。

例如,考慮如下所示的兩級陰影樹:

<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">

考慮以下程式碼:

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

扁平化樹的結構如下所示。

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

Shadow DOM 使用以下插槽 API 來檢查分發:

  • **HTMLElement.assignedSlot** - 它為元素分配插槽,如果元素沒有分配到插槽,則返回 null。

  • **HTMLSlotElement.assignedNodes** - 它提供節點列表以及插槽,並在將 flatten 選項設定為 true 時返回分發的節點。

  • **HTMLSlotElement.slotchange** - 當插槽的分發節點發生變化時,會觸發此事件。

事件重新定位

它指定事件的目標,其中元素可以在與偵聽元素相同的範圍內表示。它提供來自自定義元素的事件,看起來像是來自自定義元素標籤,而不是其中的元素。

示例

以下示例展示了在 Polymer.js 中使用事件重新定位。建立一個名為 index.html 的檔案,並將以下程式碼放入其中。

<!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>

現在,建立另一個名為 retarget-event.html 的檔案,幷包含以下程式碼。

<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>

輸出

要執行應用程式,請導航到建立的專案目錄並執行以下命令。

polymer serve

現在開啟瀏覽器並導航到**http://127.0.0.1:8081/**。輸出如下所示。

Polymer Retarget Events

單擊以上文字並開啟控制檯以檢視重新定位的事件,如下面的螢幕截圖所示。

Polymer Retarget Events

Shadow DOM 樣式

您可以使用樣式屬性為 Shadow DOM 設定樣式,這些屬性從宿主繼承到陰影樹。

示例

<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>

DOM 模板

可以使用 DOM 模板為元素建立 DOM 子樹。您可以為元素建立陰影根,並透過將 DOM 模板新增到元素來將模板複製到陰影樹中。

DOM 模板可以透過兩種方式指定:

  • 建立一個<dom-module> 元素,它應該與元素的名稱以及 id 屬性匹配。

  • 在<dom-module> 內定義一個<template> 元素。

示例

<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>

為元素的 Shadow DOM 設定樣式

Shadow DOM 允許使用樣式屬性(如字型、文字顏色和類)為自定義元素設定樣式,而無需將其應用到元素範圍之外。

讓我們使用**:host** 選擇器為宿主元素設定樣式(附加到 Shadow DOM 的元素稱為宿主)。建立一個名為 polymer-app.html 的檔案,並在其中新增以下程式碼。

<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>

如上一所示執行應用程式,並導航到**http://127.0.0.1:8000/**。輸出如下所示。

Polymer Shadow DOM Styling

為插槽內容設定樣式

可以在元素的模板中建立**插槽**,這些插槽在執行時被佔用。

示例

以下示例描述了在元素的模板中使用插槽內容。建立一個 index.html 檔案,並在其中新增以下程式碼。

<!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>

現在建立另一個名為 slotted-content.html 的檔案,幷包含以下程式碼。

<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>

如前例所示執行應用程式,並導航到**http://127.0.0.1:8081/**。輸出如下所示。

Polymer Style Slotted Content

使用樣式模組

您可以使用樣式模組在元素之間共享樣式。在樣式模組中指定樣式,並在元素之間共享它們。

示例

以下示例展示瞭如何在元素之間使用樣式模組。建立一個 index.html 檔案,並在其中新增以下程式碼。

<!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>

建立另一個名為 style-module.html 的檔案,其中包含以下程式碼。

<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>

現在,再建立一個名為colors-module.html的檔案,它為元素提供樣式模組,如下面的程式碼所示。

<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>

執行應用程式並導航到**http://127.0.0.1:8081/**。輸出如下所示。

Polymer Style Module

使用自定義屬性

自定義 CSS 屬性可用於使用 Polymer 元素為應用程式中元素的外觀設定樣式。自定義屬性提供級聯 CSS 變數,這些變數可以在自定義元素的環境之外使用,從而避免透過樣式表散佈樣式資料。

自定義屬性的定義方式類似於標準 CSS 屬性,它們從組合的 DOM 樹繼承。在前面的示例中,您可以看到為元素定義的自定義 CSS 屬性。

在 CSS 繼承下,如果元素沒有定義樣式,則它將從其父元素繼承樣式,如下面的程式碼所示。

<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>
廣告

© . All rights reserved.