iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0

我曾經看過某一篇文章是這樣說明的。如果說custom element是web component的骨架,那shadow DOM就是web component的靈魂。

使用shadow DOM

使用shadow DOM只要簡單的二步,打開Shadow DOM和把節點掛在Shadow DOM之下。但真正的關鍵(或是說麻煩?)是在使用Shadow DOM之後。

通常都是使用"element.attachShadow({mode: 'open'})"這段語法來打開shadow DOM(element請換成目標節點),'mode'的意義後面的文章會提到,這裡先跳過。

class MyComponent extends HTMLElement {
    constructor() {
        super();
        this.render = this.render.bind(this);
    }
    connectedCallback() {
        this.attachShadow({mode: 'open'});  //讓指定的節點變成Shadow DOM,這行程式碼通常照抄就好
        this.shadowRoot.appendChild(this.render()) //把節點掛在Shadow DOM之下
    }
    render() {
        const template = document.createElement('template');
        template.innerHTML = `
            <div>
                <div>
                    <slot name="slot1"></slot>
                </div>
                <div>
                    <slot></slot>
                </div>
                <div>
                    <slot name="slot2"></slot>
                </div>
            </div>
        `;
        return template.content;
    }
}

Shadow DOM的特點

shadow DOM的使用範圍

shadow DOM不是只能用在custom element,也可以用在其他HTML element。但是有些HTML element本身就有自己的shdaow DOM(比方說"select"元素)、有些HTML element則是因為安全問題(比方說"a"元素),不是所有的HTML element都能打開shadow DOM。

const divNode = document.getElementsByTagName('div')[0];
divNode.attachShadow({mode: 'open'}); // 只要使用'attachShadow',就可以讓該節點可以使用shadow DOM
divNode.shadowRoot.innerHTML = '<p>hallo world!</p>'

const aNode = document.getElementsByTagName('a')[0];
a.attachShadow({mode: 'open'}); // a不能使用Shadow DOM

shadow DOM 的外觀

shadow DOM會讓該節點原本的子節點不會顯示在畫面上(但從DOM來看還是掛在該節點之下),轉而把Shadow DOM的子節點顯示在畫面上,就像是shadow DOM的子節點才是該節點的子節點。

shadow DOM節點

外部的DOM無法使用正規方法獲得Shadow DOM的子節點(document.getElementById或是document.getElementsByClassName)。畢竟本來就是為了web component而設計的,有這種內外隔離的效果也不是不能想象。

const divNode = document.getElementsByTagName('div')[0];
divNode.attachShadow({mode: 'open'});
divNode.shadowRoot.innerHTML = '<p id='shadow'>hallo world!</p>'

document.getElementById('shadow') // 回傳為null 因為shadow DOM裡的節點不會出現在外面的DOM之中

shadow DOM和CSS

Shadow DOM的子節點,使用的CSS和外面DOM使用的CSS是獨立的,互相不會影響

使用Shadow DOM要克服的問題

Shadow DOM是為了web component才產生的技術。可以說,Shadow DOM好用的地方在模組化,不好用的地方也在模組化。

  1. Shadow DOM內外節點的分離是好事,可以防止無心的修改,可是如果要往Shadow DOM內部放入節點,就會非常麻煩了。
  2. Shadow DOM內外CSS分離是好事,畢竟CSS的全域問題一直是前端最麻煩的問題之一。也因此產生了各種CSS設定模式或CSS框架。可以保證Shadow DOM內部的CSS不會被全域影響,但如果想要讓CSS影響到Shadow DOM內部(比方說使用了Tailwind CSS)...幾乎做不到。

上一篇
[Day6] template and slot
下一篇
[Day8] web component的使用技巧-shadow DOM存取其一
系列文
web component - 次世代網頁技術的重要拼圖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言