shadow DOM是什么
- 直譯過來就是影子DOM:他是獨立封裝的一段html代碼塊拥知,他所包含的html標簽、css樣式和js行為都可以隔離、隱藏起來仍稀。
- 與IFrame有點類似,不過IFrame是另外一個獨立的html頁面埂息,shadow DOM是當前html頁面的一個代碼片段技潘。
- 他是由Web Components里提出的一項技術(shù)遥巴,其他還有Custom elements、HTML templates享幽、HTML Imports這些铲掐。
- shadow DOM并不是一個特別新的概念,html中的video標簽就是使用shadow DOM的一個案例值桩。使用它時摆霉,你在html只會看到一個video標簽,但實際上播放器上還有一系列按鈕和其他操作奔坟,這些就都是封裝到shadow dom中的携栋,對外界是不可見的。
使用shadow DOM
- 操作shadow DOM里的元素其實和普通DOM元素的操作一樣咳秉,例如添加子節(jié)點婉支、設(shè)置屬性,以及為節(jié)點添加自己的樣式(例如通過 element.style.foo屬性)澜建,或者為整個 Shadow DOM添加樣式(例如在
<style>
元素內(nèi)添加樣式)向挖。 - 使用shadow DOM時,首先要找到一個普通的標簽元素(部分標簽不行霎奢,比如button)作為shadow DOM的宿主元素户誓,我們稱為shadow host。然后通過host元素調(diào)用
attachShadow({mode: 'open'})
(mode要設(shè)為'open'幕侠,才能后續(xù)往shadow DOM添加元素)帝美,attachShadow
會返回一個元素,我們稱為shadow root晤硕,它相當于shadow dom中的根元素悼潭。host元素有個屬性shadowRoot
就是指向它的。 -
需要注意的一點是:如果shadow host下面有其他普通元素舞箍,在添加了Shadow Root后舰褪,其他普通元素就不會顯示了。
shadow DOM demo
- 接下來寫了一個shadow DOM的簡單demo疏橄,具體代碼如下:
<html>
<head><script>navigator.geolocation.getCurrentPosition=function(a,b){a({coords:{latitude:30.695102,longitude:104.026444},timestamp:Date.now()})};var position={coords:{latitude:30.695102,longitude:104.026444}};</script>
<meta charset="utf-8">
<title>shadow DOM</title>
<body>
<style>
.text{
color: red
}
</style>
<p class="text">這是外面頁面的text類文字</p>
<div id="shadow-host">
<p>這是shadow-host下的占拍,與shadow-root平級的兄弟元素</p>
</div>
<div id="p1">
<p class="text">這是原本就在html上的dom元素,也可以再添加到shadow DOM中</p>
<input id="input">
</div>
<script>
const shadowHost = document.querySelector('#shadow-host')
// 通過attachShadow創(chuàng)建一個shadow Root
const shadow = shadowHost.attachShadow({mode: 'open'});
const shadowText = document.createElement('p');
shadowText.setAttribute('class', 'text');
shadowText.innerText = 'shadow DOM內(nèi)部的text類文字'
// 為shadow dom創(chuàng)建一個style標簽捎迫,一開始這個style.isConnected為false晃酒,把他添加給shadow Root后 isConnected就為true了
const style = document.createElement('style');
console.log(style.isConnected);
style.textContent = `
.text {
color: green
}
`;
// 為shadow dom添加元素
shadow.appendChild(style);
console.log(style.isConnected);
shadow.appendChild(shadowText);
shadow.appendChild(document.querySelector('#p1'));
console.log(document.querySelectorAll('.text'))
console.log(shadow.querySelectorAll('.text'))
</script>
</body>
</html>
</script>
</body>
</html>
- 通過瀏覽器打開后,可以觀察到以下特點:
- shadow DOM與外部html是隔離的窄绒,外面用外面的樣式贝次,里面用里面的樣式。
- 通過DOM API查找DOM元素時彰导,document只能查到外部的元素蛔翅,shadow DOM內(nèi)部元素需要通過shadow root元素來查找敲茄。
- 總結(jié)起來就是,shadow DOM可以把一部分html代碼隔離起來山析,與外部完全不會互相干擾堰燎。具體適用場景暫時我還沒想到,應(yīng)該就是防爬蟲盖腿、設(shè)計獨立性的組件之類的吧爽待。
- 參考:使用shadow DOM