# 翻譯:Shadow DOM隔離釋義
使用shadow DOM的一個主要好處是樣式隔離。 要了解這意味著什麼,讓我們來假設我們要建立自定義進度條元件。 我們可以使用兩個巢狀的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 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> 複製程式碼
請注意模板元素的使用:
- 它允許作者包含HTML片段,以後可以通過克隆內容來例項化
- 模板元素可以出現在文件中的任何位置(例如,在表格和tr元素之間)
- 模板元素中的內容是惰性的,不執行指令碼或載入影象和其他型別的子資源。
這個進度條實現的問題是它的兩個內部div可以被使用者自由訪問,它的樣式規則也不侷限於進度條。 例如,為進度條定義的樣式規則將應用於進度條外部的內容,其類名為progress:
<section class="project"> <p class="progress">Pending an approval</p> </section> 複製程式碼
同樣的,為其他元素定義的樣式規則可以覆蓋進度條中的規則:
<style> .label { font-weight: bold; } </style> 複製程式碼
雖然我們可以通過使用自定義元素名稱(如custom-progressbar)來規範規則,然後通過以下方式初始化所有其他屬性來解決這些問題
all: initial 複製程式碼
但Shadow DOM提供了更優雅的解決方案,外部div處引入封裝層,以便進度條元件的使用者看不到其內部實現(例如為標籤和條建立的div)。還有為進度條定義的CSS樣式不會干擾頁面的其餘部分,反之亦然。 為此,我們首先通過呼叫在進度條上建立一個ShadowRoot:
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中的節點進行任何訪問。