宣告式 Shadow DOM:簡化 Web 元件開發的新工具

_zhiqiu發表於2024-09-12

在現代 Web 開發中,Web 元件已經成為建立模組化、可複用 UI 元件的標準工具。而 Shadow DOM 是 Web 元件技術的核心部分,它允許開發人員封裝元件的內部結構和樣式,避免元件的樣式和行為影響全域性頁面。然而,傳統的 Shadow DOM 實現方式需要透過 JavaScript 顯式地建立和附加 Shadow DOM,這增加了開發複雜性。

為了簡化 Web 元件開發,宣告式 Shadow DOM(Declarative Shadow DOM) 提供了一種新的方法,允許開發人員直接透過 HTML 定義 Shadow DOM,而無需過多依賴 JavaScript。這一特性特別適用於服務端渲染(SSR)和靜態頁面生成(SSG)場景,大大提高了頁面的載入效率和開發體驗。

本文將詳細介紹宣告式 Shadow DOM 的基礎語法、與 Javascript 的結合使用以及其主要應用場景和優勢。


一、什麼是 Shadow DOM?

Shadow DOM 是 Web 元件的一個重要組成部分,它透過建立封裝的 DOM 樹,讓元件的內部 DOM 和樣式與外部頁面隔離。這使得元件可以擁有獨立的樣式和功能,而不會與頁面的其他部分發生衝突。

傳統上,開發人員需要透過 JavaScript 呼叫 attachShadow() 方法來手動建立 Shadow DOM,並附加到自定義元素上。這樣的方式增加了程式碼的複雜性,同時在服務端渲染和靜態頁面生成中也難以直接使用。

二、宣告式 Shadow DOM 的基本語法

宣告式 Shadow DOM 允許開發人員直接在 HTML 模板中定義 Shadow DOM,而無需透過 JavaScript 來建立。這種方式依賴於 HTML 中的 <template> 標籤,並透過 shadowroot 屬性來指定 DOM 應作為 Shadow DOM 存在。

示例程式碼:

<my-element>
  <template shadowrootmode="open">
    <style>
      p {
        color: blue;
      }
    </style>
    <p>這是宣告式 Shadow DOM 內的內容!</p>
  </template>
</my-element>

在這個例子中,<template> 標籤用於定義元件的內部結構和樣式,而 shadowrootmode="open" 表示這是一個開放的 Shadow DOM,可以從外部訪問。

相比傳統的建立方式,這種宣告式的語法更加簡潔,也更利於伺服器端預渲染。

三、宣告式 Shadow DOM 與 Javascript 結合

雖然宣告式 Shadow DOM 允許在 HTML 中直接宣告元件結構,但自定義元素的行為和邏輯仍然需要透過 Javascript 來定義。例如,如果需要為元件新增互動行為,我們仍然需要編寫 JavaScript 程式碼來註冊自定義元素。

示例:宣告式 Shadow DOM + Javascript 實現計數按鈕

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <title>宣告式 Shadow DOM 示例</title>
</head>

<body>
    <!-- 定義元件的模板 -->
    <count-button>
        <template shadowrootmode="open">
            <style>
                button {
                    font-size: 16px;
                    padding: 10px 20px;
                }
            </style>
            <button id="increment-btn">點選次數:<span id="count">0</span></button>
        </template>
    </count-button>
    <script>
        // 定義自定義元素類
        class CountButton extends HTMLElement {
            constructor() {
                super();

                // 獲取按鈕和計數顯示元素
                this.button = this.shadowRoot.querySelector('#increment-btn');
                this.countDisplay = this.shadowRoot.querySelector('#count');
                this.count = 0; // 初始化計數

                // 繫結事件處理程式
                this.button.addEventListener('click', () => {
                    this.increment();
                });
            }

            // 定義一個方法來增加計數
            increment() {
                this.count++;
                this.countDisplay.textContent = this.count;
            }
        }

        // 註冊自定義元素
        customElements.define('count-button', CountButton);
    </script>

</body>

</html>

預覽

jcode

程式碼解釋:

  1. HTML 部分

    • 使用 <template> 標籤定義了計數按鈕元件的結構和樣式,並透過 shadowrootmode="open" 宣告為開放的 Shadow DOM。
    • 元件的樣式和內容在 HTML 中宣告,減少了 Javascript 中的 DOM 操作。
  2. Javascript 部分

    • 使用 Javascript 定義了一個自定義元素 CountButton
    • 新增了按鈕點選事件,每次點選按鈕時,計數器加一併更新顯示。
  3. 自定義元素註冊

    • 使用 customElements.define 方法註冊了自定義元素 <count-button>

四、宣告式 Shadow DOM 的應用場景

1. 服務端渲染(SSR)

宣告式 Shadow DOM 對服務端渲染非常友好。由於元件結構和樣式已經宣告在 HTML 中,服務端可以預先生成完整的元件,並將其直接傳送給客戶端。這不僅減少了頁面的初始載入時間,還提高了搜尋引擎的抓取能力,有利於 SEO。

2. 靜態頁面生成(SSG)

在靜態頁面生成中,宣告式 Shadow DOM 允許開發人員將預定義的元件結構嵌入到靜態 HTML 檔案中,從而提升頁面的載入速度,減少客戶端的 Javascript 計算量。

五、宣告式 Shadow DOM 的優勢與限制

優勢:

  • 簡化開發流程:透過 HTML 直接宣告 Shadow DOM,減少了對 Javascript 的依賴,降低了開發難度。
  • 效能提升:在 SSR 和 SSG 場景下,預渲染的元件可以直接傳送給客戶端,減少了首次渲染的時間。
  • SEO 友好:元件內容可以直接包含在 HTML 中,便於搜尋引擎抓取。

限制:

  • Javascript 仍不可或缺:雖然元件的結構和樣式可以宣告式定義,但元件的互動和邏輯仍需透過 JavaScript 實現。
  • 瀏覽器相容性:目前宣告式 Shadow DOM 已基本支援所有的瀏覽器,但是所需的瀏覽器的版本較新,需要開發者考慮相容性問題。

六、總結

宣告式 Shadow DOM 是 Web 元件開發的一項強大新功能,它透過簡化 Shadow DOM 的建立過程,減少了 Javascript 的依賴,特別適用於服務端渲染和靜態頁面生成場景。雖然其優勢明顯,但在實際開發中,開發者仍需結合 Javascript 來實現元件的互動和邏輯。

隨著瀏覽器對這一新特性的支援逐步增加,宣告式 Shadow DOM 將會成為 Web 元件開發中的主流方式之一。對於需要高效能、模組化的 Web 開發專案,宣告式 Shadow DOM 是一個值得嘗試的新工具。

參考資料:

  • Declarative Shadow DOM 介紹
  • Custom Elements 使用指南

相關文章