【前端幫幫忙】第2期 Shadow DOM來了解一下

Shadow DOM是什麼

顧名思義,即影子DOM,看不見摸不着,咱們沒法直接控制操縱的DOM結構。css

Mozilla對其的描述,點擊查看html

Shadow DOM 爲Web組件中的 DOM和 CSS提供了封裝。Shadow DOM 使得這些東西與主文檔的DOM保持分離。你也能夠在一個Web組件外部使用 Shadow DOM自己。前端

來看下W3CShadow DOM的描述:node

  • A shadow host is an element that hosts one or more node trees.
  • A shadow tree is a node tree hosted by a shadow host.
  • A shadow root is the root node of a shadow tree.

這三句話告訴咱們:web

  • shadow dom 由一顆或多顆 shadow tree 組成,而且須要一個普通的dom元素做爲它的容器
  • shadow tree 是一顆節點樹
  • shadow root 是shadow tree的根節點

簡單理解

咱們來寫一個小例子來加深對其的理解,寫一個簡單的滑塊標籤瀏覽器

<input type="range">
複製代碼

而後在Chrome瀏覽器按F12打開開發者工具,再按F1打開設置項,找到Show user agent shadow DOM並把其勾選上。框架

切換到Elements,咱們發現input標籤下多了#showdow-root (user agent)這個東西,它包含了input控件內部的DOM結構,這就是所謂的Shadow DOM了。dom

爲何咱們只寫了一個input標籤,會多出這麼多東西呢?實際上就是瀏覽器自動幫咱們加上的,只不過經過某種技術隱藏了起來而已。ide

那瀏覽器爲何要這麼作呢?很明顯就是讓咱們寫代碼的時候更簡單,咱們能夠再寫一個標籤來測試一下:工具

<video controls="controls" autoplay="autoplay">
  <source src="http://www.w3school.com.cn/i/movie.ogg" type="video/ogg" />
  <source src="http://www.w3school.com.cn/i/movie.ogg" type="video/mp4" />
Your browser does not support the video tag.
</video>
複製代碼

你會發現多了太多的代碼了,因此,其實是瀏覽器對某些複雜的標籤作了一層相似組件的封裝,把咱們可能無需關心的部分隱藏起來了,這樣,咱們使用的時候就能夠少寫不少代碼。

如何控制Shadow DOM?

既然是瀏覽器有意隱藏起來的DOM結構,那咱們是否能夠控制內部的DOM結構呢?並不是徹底不能夠,咱們會發現上面滑塊的Shadow DOM裏有pseudo這樣的屬性

<div pseudo="-webkit-slider-runnable-track" id="track"></div>
複製代碼

所以咱們能夠經過CSS僞元素選中該元素,而後修改它的樣式:

input::-webkit-slider-runnable-track {
    background-color: red;
}
複製代碼

能夠發現整個滑塊背景都變成了紅色。雖然這並非咱們想要的效果,但這確實是Shadow DOM開放給咱們選擇的。

不幸的是,雖然不少瀏覽器都支持Shadow DOM,但目前只有Chrome瀏覽器支持對其審查和附加選擇器。

Shadow DOM的兼容性

咱們能夠在caniuse.com查看, 查看地址

如何建立一個Shadow DOM元素?

除了原生的Shadow DOM,咱們可不能夠闖將本身的呢?

Shadow DOM必須附加在一個元素上,能夠是HTML文件中的一個元素,也能夠是腳本中建立的元素;能夠是原生的元素,如<div><p>;也能夠是自定義元素如<my-element>

其實有這樣一組API來實現的,經過Element.attachShadow()方法來爲元素附加一個Shadow DOM。來看個例子:

<div id="sd-box"></div>
複製代碼
var shadow = document.querySelector('#sd-box').attachShadow({
   mode: 'open' 
});
複製代碼

這裏的mode用來指定Shadow DOM封裝的模式,可取值有:

  • open:開放的封裝模式
  • closed:關閉的封裝模式

這時候,頁面上並無什麼變化,繼續添加下面的代碼:

shadow.innerHTML = '<p>this is Shadow DOM</p>';
複製代碼

能夠看到頁面出現上面的文本,該標籤的結構變成了

<div id="sd-box">
  #shadow-root (open)
  <p>this is shadow DOM</p>
</div>
複製代碼

證實咱們確實是經過attachShadow()方法成功爲某個元素建立了Shadow DOM。

若是想爲其添加樣式,能夠經過下面的方式來實現:

shadow.innerHTML += '<style>p { color: red; }</style>'
複製代碼

能夠發現,頁面上該標籤的字體變成了紅色。

Shadow DOM API實際上是Web Components的一部分,用來封裝組件的DOM和CSS,區別於Vue.js這樣的組件化框架,Web Components是瀏覽器原生的組件化方式,不過目前還處於初期,只有Chrome和Safari極少數瀏覽器支持。

參考

developer.mozilla.org/zh-CN/docs/…

www.cnblogs.com/WhiteCusp/p…

blog.csdn.net/u012207345/…

因爲我水平、文筆有限,若是各位在文章中發現有任何不合理,不正確的地方,還煩不吝指出,我會很是感謝的;若是經過文章有任何想法或疑問,也但願各位能積極留言,咱們互相交流探討;若是經過本文章能讓你有所收穫,能夠分享出去,讓更多的人受益。

歡迎你們關注個人公衆號,前端路上一塊兒學習成長,感謝!

相關文章
相關標籤/搜索