Thứ ba, 05/09/2017 | 00:00 GMT+7

Yếu tố tùy chỉnh đầu tiên của bạn


Vậy bạn muốn tìm hiểu về Thành phần Web và tạo các thẻ HTML tùy chỉnh của riêng mình? Trong bài đăng này, ta sẽ khám phá cú pháp và khái niệm cơ bản để cho phép bạn bắt đầu tìm hiểu với Phần tử tùy chỉnhShadow DOM .

Ta sẽ tạo một phần tử tùy chỉnh <my-title> ngớ ngẩn chỉ đơn giản là đóng dấu tiêu đề theo kiểu. Không hữu ích lắm, nhưng nó sẽ giúp chứng minh một số khái niệm ban đầu.

Bắt đầu

Trước tiên, ta sẽ tạo một file JavaScript riêng biệt sẽ chứa mọi thứ về phần tử tùy chỉnh của ta : luật kiểu, đánh dấu của nó, định nghĩa lớp ES6 và cuối cùng đăng ký phần tử tùy chỉnh. Trong các file HTML mà ta muốn sử dụng phần tử tùy chỉnh của bạn , tất cả những gì ta phải làm là bao gồm file JavaScript đó và ta sẽ sẵn sàng bắt đầu sử dụng thẻ mới trên trang của ta .

Hãy bọc mọi thứ trong IIFE để có biện pháp tốt:

my-title.js
(function() {   // the good stuff goes here })(); 

Bây giờ, hãy xác định một lớp cho phần tử tùy chỉnh của ta , lớp này sẽ mở rộng HTMLElement :

(function() {   class MyTitle extends HTMLElement {     connectedCallback() {       this.innerHTML = `         <style>           h1 {             font-size: 2.5rem;             color: hotpink;             font-family: monospace;             text-align: center;             text-decoration: pink solid underline;             text-decoration-skip: ink;           }         </style>         <h1>Hello Alligator!</h1>       `;     }   }    window.customElements.define('my-title', MyTitle); })(); 

Dưới đây là một số điều cần lưu ý:

  • Bên trong lớp ES6, điều này đề cập đến chính cá thể phần tử.
  • Phương pháp connectedCallback được kích hoạt khi các phần tử được thêm vào DOM. Ngoài ra còn có một phương thức ngắt kết nốiCallback được gọi khi xóa một phần tử khỏi DOM, hữu ích cho việc dọn dẹp những thứ như trình xử lý sự kiện.
  • Ta đăng ký (xác định) phần tử tùy chỉnh với customElement.define và chuyển vào tên thẻ làm đối số đầu tiên và sau đó là lớp xác định phần tử làm đối số thứ hai. Xác định phần tử là những gì sau đó cho phép ta sử dụng nó trong các trang HTML của bạn . Lưu ý tên thẻ phải có ít nhất hai từ, được phân tách bằng dấu gạch ngang. Đó là để ngăn bất kỳ phần tử HTML nào trong tương lai va chạm với các phần tử tùy chỉnh.

Với một phần tử tùy chỉnh đơn giản như vậy, bạn cũng có thể định nghĩa lớp dưới dạng lớp ẩn danh trực tiếp trong lệnh gọi tới customElements.define :

(function() {   window.customElements.define(     'my-title',     class extends HTMLElement {       connectedCallback() {         this.innerHTML = `           <style>             h1 {               font-size: 2.5rem;               color: hotpink;               font-family: monospace;               text-align: center;               text-decoration: pink solid underline;               text-decoration-skip: ink;             }           </style>           <h1>Hello Alligator!</h1>         `;       }     }   ); })(); 

Bạn sẽ nhận thấy rằng mọi thứ đều được chứa trong JavaScript và ta không có bất kỳ đánh dấu HTML độc lập nào. Đó là bởi vì, có lẽ không may, nhập HTML dường như đã chết trong nước, và con đường tiếp theo cho Thành phần Web sẽ là xác định đánh dấu và kiểu trong JavaScript bằng cách sử dụng các ký tự chuỗi ES6 .

Shadow DOM

Ví dụ trên là tất cả đều tốt và tốt, nhưng có một vấn đề lớn: phong cách của ta không phạm vi đến yếu tố tùy chỉnh của ta . Điều đó nghĩa là bây giờ tất cả các thẻ h1 trên các trang của ta sẽ là liên kết nóng với một gạch dưới. Để các kiểu của thành phần này không ảnh hưởng đến thế giới bên ngoài của nó, một giải pháp đặc biệt sẽ là bọc đánh dấu của ta bên trong một cái gì đó giống như div và sau đó áp dụng các kiểu bằng một bộ chọn chỉ nhắm đến shell bọc của ta :

this.innerHTML = `   <style>     .wrap-my-title h1 {       font-size: 2.5rem;       color: hotpink;       font-family: monospace;       text-align: center;       text-decoration: pink solid underline;       text-decoration-skip: ink;     }   </style>   <div class="wrap-my-tile">     <h1>Hello Alligator!</h1>   </div> `; 

Điều đó không tuyệt vời và thậm chí không tin cậy nếu có một yếu tố khác với tiêu đề wrap-my-title ở đâu đó trong đánh dấu của bạn. Thêm vào đó, sẽ hiệu quả hơn và đẹp hơn nhiều nếu ta có thể sử dụng các bộ chọn CSS đơn giản như h1 . Đây là nơi Shadow DOM xuất hiện. Shadow DOM cho phép ta phân bổ các kiểu của bạn cho các phần tử tùy chỉnh của ta để chúng không bị chảy ra ngoài.

Để sử dụng Shadow DOM, bạn gắn một gốc bóng vào phần tử và sau đó xác định đánh dấu cho phần tử bên trong root bóng:

(function() {   class MyTitle extends HTMLElement {     constructor() {       super();        this.attachShadow({ mode: 'open' });       this.shadowRoot.innerHTML = `         <style>           h1 {             font-size: 2.5rem;             color: hotpink;             font-family: monospace;             text-align: center;             text-decoration: pink solid underline;             text-decoration-skip: ink;           }         </style>         <h1>Hello Alligator!</h1>       `;     }   }    window.customElements.define('my-title', MyTitle); })(); 

Dưới đây là một số điều cần lưu ý:

  • Hàm tạo lớp là một nơi tốt để đính kèm một root bóng và định nghĩa html bên trong của nó.
  • Khi lớp của một phần tử tùy chỉnh có một phương thức khởi tạo, bạn phải luôn gọi super () trong đó.
  • Chế độ cho root bóng có thể mở hoặc đóng . Có thể bạn sẽ chỉ sử dụng open , vì nếu không, bạn sẽ không thể cài đặt bất kỳ InternalHTML nào cho nó.

Sử dụng Shadow DOM, đây là giao diện đánh dấu trong console của trình duyệt của bạn:

xem Shadow DOM trong console

Cú pháp thay thế

Bạn cũng có thể đạt được kết quả tương tự bằng cách tạo một phần tử mẫu , đặt innerHTML của nó và sau đó sao chép nội dung của mẫu dưới dạng phần tử con mới vào root bóng của ta :

(function() {   const template = document.createElement('template');    template.innerHTML = `       <style>         h1 {           font-size: 2.5rem;           color: hotpink;           font-family: monospace;           text-align: center;           text-decoration: pink solid underline;           text-decoration-skip: ink;         }       </style>       <h1>Hello Alligator!</h1>   `;    class MyTitle extends HTMLElement {     constructor() {       super();        this.attachShadow({ mode: 'open' });       this.shadowRoot.appendChild(template.content.cloneNode(true));     }   }    window.customElements.define('my-title', MyTitle); })(); 

Sử dụng

Việc sử dụng phần tử tùy chỉnh của ta cũng đơn giản như việc thêm file script vào trang và sau đó sử dụng phần tử của ta như cách ta làm với bất kỳ phần tử HTML thông thường nào khác. Tuy nhiên, lưu ý các phần tử tùy chỉnh phải luôn có thẻ đóng:

<!DOCTYPE html> <html lang="en">  <head>   <meta charset="UTF-8">   <script src="./my-counter.js"></script> </head>    <body>     <my-title></my-title>   </body>  </html> 

Lưu ý phần tử của ta chưa sẵn sàng production . Như hiện tại, phần tử sẽ chỉ hoạt động trong một số trình duyệt hiện đại. Bạn cần chạy mã thông qua trình chuyển đổi như Babel cho các tính năng JavaScript không được hỗ trợ trên bảng như các lớp ES6 hoặc các ký tự chuỗi và bạn cần sử dụng polyfills cho các phần tử tùy chỉnh và DOM bóng. Ta sẽ xem xét cách sử dụng polyfills Thành phần Web trong một bài đăng riêng.


Tags:

Các tin liên quan