国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Shadow DOM 內部構造及如何構建獨立組件

妤鋒シ / 1340人閱讀

摘要:此即如何實現局部樣式化的原理。這是一個絕佳的方式,開發者可以在組件內部封裝響應用戶交互或者狀態的行為,然后基于宿主元素來樣式化內部節點。

原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協議共享,BY Troland。

這是 JavaScript 工作原理的第十七章。

概述

網頁組件指的是允許開發者使用一系列不同的技術來創建可復用的自定義元素,組件內的功能不影響其它代碼,以便于開發者在網頁程序中使用。

有四種網頁組件標準:

Shadow DOM

HTML 模板

自定義元素

HTML Imports

本章主要討論 Shadow DOM

Shadow DOM 是一個被設計用來構建基于組件(積木式)的網頁程序的工具。它為開發者可能經常遇到過的問題提供了解決方案:

隔離的 DOM:組件的 DOM 是獨立的(比如 document.querySelector() 無法檢索到組件 shadow DOM 下的f元素節點)。這樣就可以簡化網頁程序中的 CSS 選擇器,因為 DOM 組件是互不影響,這樣就允許開發者可以隨心所欲地使用更加通用的 id/class 命名而不用擔心命名沖突。

局部樣式: shadow DOM 內定義的樣式不會污染 shadow DOM 之外的元素。Style 樣式規則不會泄漏且頁面樣式也不會污染 shadow DOM 內的元素樣式。

組合:為開發者的組件設計一個聲明式,基于標簽的接口。

Shadow DOM

本篇文章假設開發者已經對 DOM 及其 API 熟拈于心。否則,可以閱讀一下這方面的詳細資料。

與一般的 DOM 元素相比,Shadow DOM 有兩處不同的地方:

與一般創建和使用 DOM 的方式相比,開發者如何創建及使用 Shadow DOM 及其與頁面上的其它元素的關系

其展現形式與頁面上的其它元素的關系

一般情況下,開發者創建 DOM 節點,然后將其作為子元素掛載到其它元素下。對于 shadow DOM,開發者創建一個獨立 DOM 樹掛載到目標元素下而該樹和其實際子元素是分離的。該獨立子樹稱為 shadow 樹。shadow 樹的掛載元素稱為 shadow 宿主。包括 Launch 模板

當開發者不得不在網頁上復用相同的標記結構的時候,最好使用某種模板而不是重復書寫相同的頁面結構。以前是可以實現的,但是現在可以使用

可以以如下方式使用剛才使用模板創建的自定義組件:

插槽

模板有一些不足的地方,主要的不足在于靜態內容不允許開發者像一般的標準 HTML 模板那樣渲染自定義的變量或者數據。

這時候 就派上用場了。

可以把插槽看成是允許開發者在模板中放置自定義 HTML 的占位符的功能。這樣開發者就可以創建能用的 HTML 模板并且通過引入插槽來自定義渲染內容。

讓我們看一下以上模板添加一個插槽的代碼如下:

如果在標記中引用該元素的時候沒有定義插槽內容,或者瀏覽器不支持插槽,則 只會包含默認的 "Default text" 內容。

若想要定義插槽內容,開發者得在 中定義元素 HTML 結構的 slot 屬性值和對應填充的插槽名稱保持一致即可。

如前所述,開發者可以隨便寫插槽內容:


 Let"s have some different text!

所有可以被插入插槽的元素被稱為可插入元素;已插入插槽元素稱為插槽元素。

注意以上示例中插入的 元素即是插槽元素。它擁有一個 slot 屬性,屬性值和模板中插槽定義的 name 屬性值相等。

瀏覽器渲染之后,以上代碼會創建如下扁平 DOM 樹:


  #shadow-root
  

Default text

Let"s have some different text!

這里原文有誤,有改動。

注意 #shadow-root 元素只是表示存在 Shadow DOM 而已。

樣式化

可以在主頁面樣式化含有 shadow DOM 的組件,可以定義組件樣式或者提供 CSS 自定義屬性的形式讓用戶覆蓋掉默認樣式值。

組件定義的樣式

局部樣式 是 Shadow DOM 極好的功能之一:

主頁面上的 CSS 選擇器不會影響到組件內部元素的樣式。

組件內部定義的樣式不會影響頁面上的其它元素樣式。它們只作用于宿主元素。

Shadow DOM 中的 CSS 選擇器只影響組件內部的元素。實際上,這意味著開發者可以重復使用通用的 id/class 名稱而不用擔心和主頁面上的其它樣式發生沖突。簡單的 CSS 選擇器可以提高頁面性能。

讓我們看一下如下 #shadow-root 中定義的一些樣式:

#shadow-root


以上示例中的樣式只會作用于 #shadow-root 內部。

開發者也可以在 #shadow-root 里面使用 元素來引入樣式表,也只作用于 #shadow-root 內部。

:host 偽類

:host 偽類允許開發者選擇和樣式化包含 shadow 樹的宿主元素:

只有一個地方需要注意即若主頁面上定義的宿主元素樣式優先級比元素里面定義的 :host 樣式規則要高。這樣就允許開發者從外部覆蓋掉組件內部定義的頂級樣式。

即當在主頁面上定義了如下的樣式:

my-paragraph {
  marbin-bottom: 40px;
}

同理,:host 只在shadow 根的上下文中起作用,因此開發者不能夠在 Shadow DOM 外面使用。

:host() 這樣的功能樣式允許開發者只樣式化匹配 的宿主元素。這是一個絕佳的方式,開發者可以在組件內部封裝響應用戶交互或者狀態的行為,然后基于宿主元素來樣式化內部節點。

使用 :host-context() 偽類來定制化元素樣式

:host-context() 偽類找出宿主元素或者宿主元素任意的祖先元素匹配

常用于定制化。例如,開發者通過為 或者 添加類來進行定制化:


  

或者

當宿主元素的祖先元素包含有 .lightheme 類 :host-context(.lightheme) 將會樣式化

:host-context(.lightheme) {
  color: black;
  background: white;
}

可以使用 :host-context() 來進行定制化主題樣式,但是更好的方法即通過 CSS 自定義屬性來創建樣式鉤子。

從外部樣式化組件宿主元素

開發者可以從外部通過把標簽名作為選擇器來樣式化組件宿主元素,如下:

custom-container {
  color: red;
}

外部樣式比 Shadow DOM 中定義的樣式擁有更高的優先級。

例如,假設用戶書寫如下選擇器:

custom-container {
  width: 500px;
}

將會覆蓋如下組件樣式規則 :

:host {
  width: 300px;
}

組件自身樣式化只能做到這么多。但如果想要樣式化組件內部屬性呢?這就需要 CSS 自定義屬性。

使用 CSS 自定義屬性來創建樣式鉤子

若組件作者使用 CSS 自定義屬性提供樣式鉤子,用戶可以用來更改內部樣式。

這和 思路類似只是應用到了樣式。

讓我們看如下示例:




Shadow DOM 內部:

:host([background]) {
  background: var(--custom-container-bg, #CECECE);
  border-radius: 10px;
  padding: 10px;
}

該示例中,因為用戶提供了該背景顏色值,所以組件將會把黑色作為背景顏色值。否則,默認為 #CECECE

作為組件作者,需要讓開發者知道可以使用的 CSS 自定義屬性。可以把自定義屬性看作組件的公共接口。

插槽 JavaScript 接口

Shadow DOM API 可能用來操作插槽。

slotchange 事件

當一個插槽的分發元素節點發生變化的時候觸發 slotchange 事件。例如,當用戶從 light DOM 中添加/刪除子節點。

var slot = this.shadowRoot.querySelector("#some_slot");
slot.addEventListener("slotchange", function(e) {
  console.log("Light DOM change");
});

可以在元素的構造函數中創建 MutationObserver 來監聽 light DOM 的其它類型的修改事件。前面文章中有介紹過 MutationObserver 的內部構造及使用指南。

assignedNodes() 方法

了解哪些元素是和插槽有關是很有用處的。調用 slot.assignedNodes() 可以找出哪些元素是由插槽渲染的。flatten: true} 選項會返回插槽的默認內容(若沒有分發任何節點)。

看一下如下示例:

Default content

假設以上內容包含在一個叫做 的組件內部。

讓我們查看一下該組件的不同用法,然后調用 assignedNodes() 輸出不同的結果:

第一例中,我們將往插槽中添加內容:


   container text 

調用 assignedNodes() 將會返回 [ container text ]。注意結果為一個節點數組。

第二例中,將不添加內容:

調用 assignedNodes() 將會返回空數組 []

但是,假設添加 {flatten: true} 參數將會返回默認內容:[

Default content

]

同理,為了查找插槽中的元素,開發者可以調用 assignedNodes() 來找出元素被掛載到哪個組件插槽中。

事件模型

Shadow DOM 中的事件冒泡的經過是值得注意的。

事件目標被調整為維護 Shadow DOM 的封閉性。當事件被重新定位,看起來是由組件自身產生而不是組件的 Shadow DOM 內部元素。

這里有傳播出 Shadow DOM 的事件列表(還有一些只能在 Shadow DOM 內傳播):

Focus 事件:blur, focus, focusin, focusout

鼠標事件:click, dblclick, mousedown, mouseenter, mousemove 等.

滾輪事件: wheel

輸入事件: beforeinput, input

鍵盤事件: keydown, keyup

組合事件: compositionstart, compositionupdate, compositionend

拖拽事件: dragstart, drag, dragend, drop 等.

自定義事件

默認情況下,自定義事件不會傳播出 Shadow DOM。開發者若想要分派自定義事件且想要傳播出 Shadow DOM,需要添加 bubbles: truecomposed: true 選項參數。

讓我們瞧瞧類似這樣的事件分派:

var container = this.shadowRoot.querySelector("#container");
container.dispatchEvent(new Event("containerchanged", {bubbles: true, composed: true}));
瀏覽器兼容情況

可以通過檢查 attachShadow 來檢查是否支持 Shadow DOM 功能:

const supportsShadowDOMV1 = !!HTMLElement.prototype.attachShadow;

參考資料:

https://developer.mozilla.org...

https://developers.google.com...

https://developer.mozilla.org...

https://www.html5rocks.com/en...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102259.html

相關文章

  • JavaScript 是如何工作: Shadow DOM內部結構+如何編寫獨立組件

    摘要:向影子樹添加的任何內容都將成為宿主元素的本地元素,包括,這就是影子實現樣式作用域的方式。 這是專門探索 JavaScript 及其所構建的組件的系列文章的第 17 篇。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! 如果你錯過了前面的章節,可以在這里找到它們: JavaScript 是如何工作的:引擎,運行時和調用堆棧的概述! JavaScript 是如何工作...

    godlong_X 評論0 收藏0
  • 純原生組件化-模塊化的探索

    摘要:純原生的組件化模塊化的一次小小的嘗試,用到了如下幾個新特性對標簽結構的一個封裝,真正意義上的組件,能保證中的元素不會被外界影響,內部也不會影響到外部的行為,變成了一個獨立的模塊。 純原生的組件化、模塊化的一次小小的嘗試,用到了如下幾個新特性:shadown-DOM 對HTML標簽結構的一個封裝,真正意義上的組件,能保證 shadow-DOM 中的DOM元素不會被外界影響,內部也不會影響...

    張金寶 評論0 收藏0
  • 自定義元素探秘構建可復用組件最佳實踐

    摘要:若自定義元素標簽名稱不可用則摒棄。總之,自定義元素讓開發者的代碼更易理解和維護,并分割為小型,可復用及可封裝的模塊。被稱為自定義元素接口,雖然現在仍然可用,但是已經被棄用并被認為是糟糕的實現。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協議共享,BY Troland。 這是 JavaScript 工作原理第十九章。 概述 在 前述文章中,我們介紹了 Shadow ...

    CoorChice 評論0 收藏0
  • # Web Components 全攬

    摘要:定制元素可以在原生元素外創建定制元素。此定制元素內部有一個加號按鈕,一個減號按鈕,一個顯示當前值。此主題會在下一部分內介紹。定制元素的屬性元素的屬性被稱為,對象內的屬性被稱為。做響應的同步處理。 Web Components 全攬 Web Components技術可以把一組相關的HTML、JS代碼和CSS風格打包成為一個自包含的組件,只要使用大家熟悉的標簽即可引入此組件。Web Com...

    legendmohe 評論0 收藏0

發表評論

0條評論

妤鋒シ

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<