Polymer - Shadow DOM và Tạo kiểu

Shadow DOM là một thuộc tính mới của DOM được sử dụng để xây dựng các thành phần.

Example

Trong đoạn mã sau, thành phần tiêu đề bao gồm tiêu đề trang và nút menu.

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

Shadow DOM cho phép định vị các con trong một cây con có phạm vi, được gọi là shadow tree.

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

Gốc shadow-root được gọi là phần trên cùng của cây bóng và phần tử được gắn vào cây được gọi là máy chủ bóng (header-demo). Máy chủ bóng tối này bao gồm một thuộc tính gọi là shadowRoot, chỉ định gốc bóng tối. Gốc bóng xác định phần tử máy chủ bằng cách sử dụng thuộc tính máy chủ.

Shadow DOM và Thành phần

Cây bóng có thể được hiển thị thay vì con của phần tử, nếu có một phần tử trong DOM bóng. Phần tử con của phần tử có thể được hiển thị bằng cách thêm phần tử <slot> vào cây bóng.

Ví dụ: sử dụng cây bóng sau cho <header-demo>.

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

Thêm phần tử con vào phần tử <my-header> dưới dạng -

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

Tiêu đề thay thế phần tử </slot> bằng các phần tử con được chỉ định ở trên là -

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

Nội dung dự phòng

Nội dung dự phòng có thể được hiển thị khi không có nút nào được phân bổ cho vị trí. Ví dụ -

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

Bạn có thể cung cấp biểu tượng của riêng mình cho một phần tử dưới dạng:

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

Phân phối đa cấp

Bạn có thể phân bổ phần tử vị trí cho một vị trí, được gọi là phân phối nhiều cấp.

Ví dụ: lấy hai cấp độ của một cây bóng như hình dưới đây -

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

Hãy xem xét đoạn mã sau:

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

Cấu trúc của một cây dẹt trông như sau.

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

Shadow DOM sử dụng các API Slot sau để kiểm tra phân phối -

  • HTMLElement.assignedSlot - Nó phân bổ vị trí cho một phần tử và trả về null, nếu không có cấp phát phần tử cho một vị trí.

  • HTMLSlotElement.assignedNodes - Nó cung cấp danh sách các nút cùng với vị trí và trả về các nút được phân phối, khi bạn đặt tùy chọn làm phẳng thành true.

  • HTMLSlotElement.slotchange - Sự kiện này kích hoạt khi có những thay đổi trong các nút phân tán của vị trí.

Nhắm mục tiêu lại sự kiện

Nó chỉ định mục tiêu của sự kiện trong đó phần tử có thể được biểu diễn trong cùng phạm vi với phần tử lắng nghe. Nó cung cấp một sự kiện từ một phần tử tùy chỉnh, có vẻ như nó đến từ thẻ phần tử tùy chỉnh, trái ngược với một phần tử bên trong.

Example

Ví dụ sau cho thấy việc sử dụng nhắm mục tiêu lại sự kiện trong Polymer.js. Tạo một tệp có tên là index.html và đặt đoạn mã sau vào đó.

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

Bây giờ, hãy tạo một tệp khác có tên là retarget-event.html và bao gồm đoạn mã sau.

<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

Để chạy ứng dụng, hãy điều hướng đến thư mục dự án đã tạo và chạy lệnh sau.

polymer serve

Bây giờ, hãy mở trình duyệt và điều hướng đến http://127.0.0.1:8081/. Sau đây sẽ là đầu ra.

Nhấp vào văn bản trên và mở bảng điều khiển để xem sự kiện được nhắm mục tiêu lại như được hiển thị trong ảnh chụp màn hình sau.

Tạo kiểu Shadow DOM

Bạn có thể tạo kiểu cho DOM bóng bằng cách sử dụng các thuộc tính kiểu, các thuộc tính này kế thừa từ máy chủ đến cây bóng.

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>

DOM Templating

Cây con DOM có thể được tạo cho một phần tử bằng cách sử dụng DOM templating. Bạn có thể tạo gốc bóng cho phần tử và sao chép mẫu vào cây bóng bằng cách thêm mẫu DOM vào một phần tử.

Mẫu DOM có thể được chỉ định theo hai cách:

  • Tạo phần tử <dom-module>, phần tử này phải khớp với tên của phần tử cùng với thuộc tính id.

  • Xác định một phần tử <template> bên trong <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>

Tạo kiểu cho Shadow DOM của một phần tử

Shadow DOM cho phép tạo kiểu cho các phần tử tùy chỉnh bằng cách sử dụng các thuộc tính tạo kiểu như phông chữ, màu văn bản và lớp mà không cần áp dụng nó bên ngoài phạm vi phần tử của bạn.

Hãy tạo kiểu cho phần tử chủ bằng cách sử dụng :hostbộ chọn (một phần tử gắn với DOM bóng được gọi là máy chủ). Tạo một tệp có tên polyme-app.html và thêm mã sau vào đó.

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

Chạy ứng dụng như được hiển thị trong chương trước và điều hướng đếnhttp://127.0.0.1:8000/. Sau đây sẽ là đầu ra.

Nội dung có rãnh tạo kiểu

Có thể tạo slots trong mẫu của một phần tử, được sử dụng tại thời điểm chạy.

Example

Ví dụ sau đây mô tả việc sử dụng nội dung có rãnh trong mẫu của phần tử. Tạo tệp index.html và thêm mã sau vào đó.

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

Bây giờ hãy tạo một tệp khác có tên slotted-content.html và bao gồm đoạn mã sau.

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

Chạy ứng dụng như được hiển thị trong ví dụ trước và điều hướng đến http://127.0.0.1:8081/. Sau đây sẽ là đầu ra.

Sử dụng mô-đun kiểu

Bạn có thể chia sẻ kiểu giữa các phần tử cùng với các mô-đun kiểu. Chỉ định các kiểu trong mô-đun kiểu và chia sẻ chúng giữa các phần tử.

Example

Ví dụ sau đây cho thấy cách sử dụng mô-đun kiểu giữa các phần tử. Tạo tệp index.html và thêm mã sau vào đó.

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

Tạo một tệp khác có tên style-module.html với mã sau.

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

Bây giờ, hãy tạo thêm một tệp có tên là Colors-module.html , tệp này cung cấp các mô-đun kiểu cho các phần tử như được hiển thị trong đoạn mã sau.

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

Chạy ứng dụng và điều hướng đến http://127.0.0.1:8081/. Sau đây sẽ là đầu ra.

Sử dụng thuộc tính tùy chỉnh

Các thuộc tính CSS tùy chỉnh có thể được sử dụng để tạo kiểu dáng cho phần tử trong ứng dụng của bạn bằng cách sử dụng phần tử Polymer. Thuộc tính tùy chỉnh cung cấp các biến CSS xếp tầng, có thể được sử dụng bên ngoài môi trường của các phần tử tùy chỉnh để tránh phân tán dữ liệu kiểu thông qua biểu định kiểu.

Các thuộc tính tùy chỉnh có thể được định nghĩa tương tự như các thuộc tính CSS chuẩn, được kế thừa từ cây DOM đã tổng hợp. Trong ví dụ trước, bạn có thể thấy các thuộc tính CSS tùy chỉnh được xác định cho các phần tử.

Theo kế thừa CSS, nếu không có kiểu nào được xác định cho một phần tử, thì nó sẽ kế thừa kiểu từ cha của nó như được hiển thị trong đoạn mã sau.

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