Web Components系列(四) —— 認識 Shadow DOM

shadowdom.001

前言

在初涉前端之時,我就一直在好奇一個問題,為什么像:

  • <input/>
  • <select></select>
  • <audio></audio>
  • <video></video>
  • ……

等等這些標簽,看起來似乎很簡單,可為什么可以展現出那么豐富復雜的布局?當時我給自己的解釋是:這些標簽都是系統控制渲染的。

現在想想,那么解釋好像有點道理,但終歸沒有涉及到本質原因,專家級的解釋應該是:以上這些元素都是以組件的方式存在,所展現出來的那些布局都是在組件內部定義好的,如果頁面引用了這些元素標簽,那它內部的布局都會渲染在頁面上

在介紹 Web Components 時講到,它的第二項技術規范為 Shadow DOM。通過了解 Shadow DOM 的相關知識,或許可以解開上面的疑惑。

查看默認組件的 Shadow DOM

有人可能疑惑,既然說文章開頭列舉的那些元素是組件,那為什么我在開發者工具中看到的結構是這樣的:

image-20220209164432603

有什么辦法可以看到各個組件內部的 DOM 結構嗎?答案是有的,步驟如下:

第一步:打開開發者工具,點擊右上角的設置圖標:

image-20220209164713615

第二步:找到偏好設置-元素,然后對 “顯示用戶代理 Shadow DOM” 進行選中:

image-20220209164834841

這時候,我們再查看那些默認組件的內部結構,如下所示:

image-20220209165056702

可以看到,這些默認標簽下都包含一個 “shadow root” 而在 shadow root 中包含的是具體布局:

image-20220209165539233

一個看似簡簡單單的 audio 元素,里面的布局還蠻復雜的。這不禁讓我想到一句話:功夫都在舞臺外

在上面的截圖中,我們看到了 “shadow root” ,它其實是 Shadow DOM 的一部分。

Shadow DOM 的概念

在介紹概念之前,我們先來看看 “shadow” 這個單詞的中文釋義:

image-20220209161512842

Shadow DOM,翻譯過來就是“影子 DOM” 。

影子當然都是藏在暗處,不容易讓人發現的,就像文章開頭提到的那些默認元素,如果不通過設置,我們表面上看到的就是簡單的一個標簽而已。

專業的解釋就是:Shadow DOM 是 HTML 的一個規范 ,它允許瀏覽器開發者封裝自己的HTML 標簽、CSS 樣式和特定的 Javascrip 代碼,同時也可以讓開發人員創建類似 <video> 這樣的自定義標簽。

Shadow DOM 的意義

“組件化”備受追捧的原因自然是因為它獨特的魅力,我們只需要將定義好的組件通過簡單的一組標簽引入頁面,就可以得到預定好的效果,并且可以在多處使用。

而 Shadow DOM 能在 Web Components 體系中占據重要的地位,是因為其具有良好的密封性,主要表現在:

  • 隱藏標記、樣式和行為;
  • 保持代碼隔離,保證頁面的干凈整潔,各組件內部代碼互不影響;
  • 隱藏實現細節,便于使用更強大的語法或功能。

這就意味著,如果我們使用了 Shadow DOM,那就可以在它內部隨意的發揮,而不必擔心這些發揮會影響到頁面的其他部分,變相地給了開發人員極大的自由。

想想曾經小心翼翼地定義樣式、綁定事件的時光吧,懷念嗎?

Shadow DOM 結構

Shadow DOM 允許將隱藏的 DOM 樹附加到常規的 DOM 樹中——它以 Shadow root 節點為起始根節點,在這個根節點的下方,可以是任意元素,和普通的 DOM 元素一樣,借用網上的一張圖片:

img

下面是我根據自己的理解畫出來的:

image-20220209182955624

大家根據自己喜好,看哪一張更容易理解就對著哪張看,都無所謂的。對應到實際的文檔中,其結構如下:

image-20220209224058708

在以上的結構圖中,我們看到了幾個陌生的名詞,包括我們在之前看到的 “shadow root”,它們都是 Shadow DOM 的術語,接下來我解釋一下它們各自的含義。

Shadow DOM 術語

Shadow host

一個常規 DOM節點,Shadow DOM 會被附加到這個節點上。

Shadow tree

Shadow DOM內部的DOM樹。

Shadow boundary

Shadow DOM 分界線。Shadow DOM 結束的地方,也是常規 DOM 開始的地方。

Shadow root

Shadow tree 的根節點。

用法

掛載 Shadow DOM

可使用 Element.attachShadow() 方法給指定的元素掛載一個Shadow DOM,并且返回對 ShadowRoot 的引用。

let hostEle = document.getElementById("myCard");
let shadowroot = hostEle.attachShadow({mode: "open"});

控制 Shadow DOM

你可以使用同樣的方式來操作 Shadow DOM,就和操作常規 DOM 一樣——例如添加子節點、設置屬性,以及為節點添加自己的樣式(例如通過 element.style 屬性),或者為整個 Shadow DOM 添加樣式(例如在 <style> 元素內添加樣式)。不同的是,Shadow DOM 內部的元素始終不會影響到它外部的元素(除了 :focus-within 元素內添加樣式),這為封裝提供了便利。

注意事項

如果一個元素底下已經有一個 Shadow DOM 掛載,繼續給它掛載的話,會報錯:

image-20220209224818484

結束語

Shadow DOM 的主要作用就是其封裝的特性,使得各組件的內部代碼互不干擾,提供一個安全的開發運行環境。

關于 Shadow DOM 的基本概念就先介紹這么多,接下來將介紹它的操作方法。

~

~ 本文完,感謝閱讀!

~

學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!

大家好,我是〖編程三昧〗的作者 隱逸王,我的公眾號是『編程三昧』,歡迎關注,希望大家多多指教!

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,430評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,134評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,893評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,653評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,136評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,372評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,888評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,738評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,179評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,588評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,829評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,610評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,916評論 2 372

推薦閱讀更多精彩內容