# 翻譯:Shadow DOM隔離釋義

使用shadow DOM的一個主要好處是樣式隔離。 要了解這意味着什麼,讓咱們來假設咱們要建立自定義進度條組件。 咱們可使用兩個嵌套的DIV來顯示條形,使用另外一個DIV來顯示文本以顯示百分比,以下所示:web

<style>
.progress { position: relative; border: solid 1px;width: 100px; height: 1rem; }
.progress > .bar { background: red; height: 100%; }
.progress > .label {
  position: absolute; top: 0;
  width: 100%;
    text-align: center; font-size: 0.8rem;}
</style>
<template id="progress-bar-template">
    <div class="progress">
        <div class="bar"></div>
        <div class="label">0%</div>
    </div>
</template>
<script>
function createProgressBar() {
    var fragment = document.getElementById('progress-bar-template').content.cloneNode(true);
    var progressBar = fragment.querySelector('div');
    progressBar.updateProgress = function (newPercentage) {
      var ps =  newPercentage + '%'
      this.querySelector('.label').textContent = ps 
        this.querySelector('.bar').style.width = ps
    }
    return progressBar;
}
var p =  createProgressBar()
document.body.appendChild(p)
p.updateProgress(22)
</script>
複製代碼

請注意模板元素的使用:api

  1. 它容許做者包含HTML片斷,之後能夠經過克隆內容來實例化
  2. 模板元素能夠出如今文檔中的任何位置(例如,在表格和tr元素之間)
  3. 模板元素中的內容是惰性的,不運行腳本或加載圖像和其餘類型的子資源。

這個進度條實現的問題是它的兩個內部div能夠被用戶自由訪問,它的樣式規則也不侷限於進度條。 例如,爲進度條定義的樣式規則將應用於進度條外部的內容,其類名爲progress:app

<section class="project">
    <p class="progress">Pending an approval</p>
</section>
複製代碼

一樣的,爲其餘元素定義的樣式規則能夠覆蓋進度條中的規則:dom

<style>
.label { font-weight: bold; }
</style>
複製代碼

雖然咱們能夠經過使用自定義元素名稱(如custom-progressbar)來規範規則,而後經過如下方式初始化全部其餘屬性來解決這些問題this

all: initial
複製代碼

但Shadow DOM提供了更優雅的解決方案,外部div處引入封裝層,以便進度條組件的用戶看不到其內部實現(例如爲標籤和條建立的div)。還有爲進度條定義的CSS樣式不會干擾頁面的其他部分,反之亦然。 爲此,咱們首先經過調用在進度條上建立一個ShadowRoot:spa

attachShadow({mode: 'closed'})
複製代碼

而後在其下附加其實現所需的各類DOM實現。 假設咱們仍然使用div來掛接這個Shadow Root,以下所示:翻譯

<body>
<template id="progress-bar-template">
    <div class="progress">
        <div class="bar"></div>
        <div class="label">0%</div>
    </div>
<style>
.progress { position: relative; border: solid 1px;width: 100px; height: 1rem; }
.progress > .bar { background: red; height: 100%; }
.progress > .label {
  position: absolute; top: 0;
  width: 100%;
    text-align: center; font-size: 0.8rem;}
</style>
</template>
<script>
function createProgressBar() {
    var progressBar = document.createElement('div');
    var shadowRoot = progressBar.attachShadow({mode: 'closed'});
    shadowRoot.appendChild(document.getElementById('progress-bar-template').content.cloneNode(true));
    progressBar.updateProgress = function (newPercentage) {
        shadowRoot.querySelector('.label').textContent = newPercentage + '%';
        shadowRoot.querySelector('.bar').style.width = newPercentage + '%';
    }
    return progressBar;
}
var p =  createProgressBar()
document.body.appendChild(p)
p.updateProgress(22)
</script></body>
複製代碼

請注意,style元素位於模板元素內部,並與div一塊兒克隆到Shadow Root內。這容許在陰影根中定義的樣式規則做用域。 在陰影根以外定義的樣式規則就沒法適用於Shadow Root內的元素。設計

使用打開模式,您能夠經過HTML元素的shadowRoot屬性訪問Shadow DOM。關閉模式你不能。 shadowRoot將返回null。封閉模式的設計目標是禁止對來自外部世界的Shadow Root中的節點進行任何訪問。code

翻譯來自:

Introducing Slot-Based Shadow DOM API | WebKitblog

相關文章
相關標籤/搜索