顾名思义,即影子DOM,看不见摸不着,咱们没法直接控制操纵的DOM结构。css
Mozilla对其的描述,点击查看:html
Shadow DOM 为Web组件中的 DOM和 CSS提供了封装。Shadow DOM 使得这些东西与主文档的DOM保持分离。你也能够在一个Web组件外部使用 Shadow DOM自己。前端
来看下W3C
对Shadow DOM
的描述:node
这三句话告诉咱们:web
咱们来写一个小例子来加深对其的理解,写一个简单的滑块标签浏览器
<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>
复制代码
你会发现多了太多的代码了,因此,其实是浏览器对某些复杂的标签作了一层相似组件的封装,把咱们可能无需关心的部分隐藏起来了,这样,咱们使用的时候就能够少写不少代码。
既然是浏览器有意隐藏起来的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浏览器支持对其审查和附加选择器。
咱们能够在caniuse.com查看, 查看地址
除了原生的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/…
因为我水平、文笔有限,若是各位在文章中发现有任何不合理,不正确的地方,还烦不吝指出,我会很是感谢的;若是经过文章有任何想法或疑问,也但愿各位能积极留言,咱们互相交流探讨;若是经过本文章能让你有所收获,能够分享出去,让更多的人受益。
欢迎你们关注个人公众号,前端路上一块儿学习成长,感谢!