Shadow DOM系列6-綜述

Web Components 系列主要由自定義元素(Custom Elements)HTML 引入(HTML Imports)影子 DOM(shadow DOM) 組成,而 Shadow DOM 無疑是當中的重中之重。本文對下面翻譯的幾篇文章進行綜述,總結了 Shadow DOM 術語梳理和結構關係。html

術語標註


  • 影子 DOM(shadow DOM):是一種依附於文檔原有節點的子 DOM,具備封裝性html5

  • 光明 DOM(light DOM):就是原生的 DOM,爲了與影子 DOM 區別採用的名詞node

  • 影子樹(shadow trees):特指存在於 shadow DOM 中的節點結構web

  • 影子宿主(shadow host):特指 shadow DOM 所依附的影子宿主,是存在於原生 DOM 中的節點dom

  • 影子根(shadow root):指 shadow DOM 的根節點ide

  • 插入點(insertion point):指 shadow DOM 中的 <content> 標籤spa

  • 貪心插入點(greedy insertion point):指使用通配符選擇器進行匹配的插入點.net

  • 影子邊界(shadow boundary):指對影子 DOM 與光明 DOM 進行的樣式隔離,二者中的樣式不會相互影響。翻譯

  • 分佈節點(distributed nodes):指本來存在於光明 DOM 結構中,被 <content> 標籤添加到影子 DOM 中的節點。code

結構關係

影子 DOM 必須依附於一個文檔中的原有 DOM 節點,也就是影子宿主,而影子 DOM 中的節點也能夠成爲另外一個影子樹的宿主。在 Web Components 的實際使用場景中,宿主通常是自定義元素,而在影子 DOM 中封裝了其實現細節。

影子 DOM 樹被影子邊界所包裹,邊界給其帶來了封裝性,這一封裝性包括:

  1. DOM 的封裝性:在不一樣的 DOM 樹中沒法選擇另外 DOM 中的元素,只有獲取對應的 DOM 樹才能對其中的元素進行操做;

  2. 樣式的封裝性:在不一樣的 DOM 樹中樣式沒法相互影響,只有經過一系列手段突破邊界才能對對方的樣式進行操做。其中經過影子 DOM 來對宿主 DOM 進行操做的方式多種多樣:

    須要注意的是,單獨使用 ::content 選擇器沒有意義,這表示對插入點進行的樣式修飾,而插入點是不展示的;因此該選擇器的出現必然跟隨者子選擇器,以便對分佈節點進行樣式影響。

    而光明 DOM 對於影子 DOM 的影響卻要弱不少,且原則上來說,影子 DOM 存在的意義就是爲了對子 DOM 進行封裝,而實現自定義元素對外部隱藏細節的效果。若是用戶要求進行影響的話,這裏也存在兩個大殺器:一層穿透 ::shadow 僞類選擇器與多重穿透 /deep/ 組合符。

    • 對宿主自己進行樣式影響:經過 :host 選擇器

    • 對宿主的祖先節點進行樣式影響:經過 :host-context 選擇器

    • 對分佈節點進行影響:經過 ::content 選擇器

  3. JS 的重定向與阻塞:影子邊界對於 JS 的阻塞是最弱的,它僅僅阻塞了一部分事件, 同時將影子 DOM 中的事件重定向到宿主上。關於事件重定向,Eric Bidelman 的 Shadow DOM 301 講的更爲細緻一點,事實上重定向僅僅是表示影子 DOM 中的事件冒泡沒法經過影子邊界,而在邊界內部的事件監聽仍是有效果的。咱們也能夠經過 event.path 來查看調整後的事件路徑,並找到事件在影子 DOM 中的真正源頭。

光明 DOM 與影子 DOM 的結構關係以下圖所示:

結構關係圖

圖中藍線表示樣式影響方式,紅線表示 DOM 影響方式,黃線表示 JS 影響方式。

一些注意的內容

  1. 在影子 DOM 中,<link> 標籤時被忽略的,所以不能用外鏈的方式引入 CSS 文件。在 Polymer 中咱們能夠這樣作,是由於 Polymer 將 <link> 節點轉化爲了 <style> 節點所致。在原生的實現上要注意這一點。

譯文集合

  1. Shadow DOM系列1-簡介

  2. Shadow DOM系列2-基礎

  3. Shadow DOM系列3-樣式

  4. Shadow DOM系列4-樣式(續)

  5. Shadow DOM系列5-JavaScript

相關文章
相關標籤/搜索