前言刚接触前端的时候,一直很好奇一个问题,为什么是这样的:音频<视频>视频>...等等。这些标签看似很简单,但为什么能表现出如此丰富复杂的布局呢?我当时给自己的解释是:这些标签是系统控件渲染的。现在想来,这个解释似乎有道理,但毕竟不涉及本质原因。专家级的解释应该是:以上元素以组件的形式存在,显示的布局都是在组件内部定义的,如果页面引用了这些元素标签,它的内部布局将呈现在页面上。在介绍WebComponents的时候提到它的第二个技术规范是ShadowDOM。通过了解ShadowDOM的相关知识,上述疑惑或许可以迎刃而解。查看默认组件的ShadowDOM,可能有人会疑惑,既然文章开头列出的元素都是组件,为什么我在开发者工具中看到的结构是这样的:有没有办法看到DOM结构每个组件内部??答案是肯定的,步骤如下:第一步:打开开发者工具,点击右上角的设置图标:第二步:找到首选项-元素,选择“显示用户代理ShadowDOM”:在这个这时,我们再看看那些默认组件的内部结构,如下图:可以看到,这些默认标签都包含一个“shadowroot”,而shadowroot包含一个具体的layout:一个看似简单的audio元素,该layout里面相当复杂。这不禁让我想起一句话:功夫全在台外。在上面的截图中,我们看到了“shadowroot”,它实际上是ShadowDOM的一部分。ShadowDOM的概念在介绍概念之前,我们先来看看“影”字的中文解释:ShadowDOM,译为“影子DOM”。当然,人影都是隐藏在暗处,不容易被人发现。就像文章开头提到的默认元素一样,如果我们不通过设置,表面上看到的只是一个简单的标签。专业的解释是:ShadowDOM是HTML的一种规范,它允许浏览器开发者封装自己的HTML标签、CSS样式和特定的Javascrip代码,也允许开发者像这样创建自定义标签。ShadowDOM的“组件化”之意之所以备受追捧,自然是因为其独特的魅力。我们只需要通过简单的一组标签,将定义好的组件引入到页面中,就可以得到预定的效果,并且可以随处多用。ShadowDOM之所以能在WebComponents体系中占据重要地位,是因为它具有良好的密封性能,主要表现在:隐藏标签、样式和行为;保持代码隔离,保证页面干净整洁,各组件内部代码互斥。影响;隐藏实现细节以支持更强大的语法或功能。这意味着,如果我们使用ShadowDOM,我们可以在其中自由发挥,而不必担心这些发挥会影响页面的其他部分,从而变相地为开发人员提供了极大的自由。想想你以前小心翼翼地定义样式和绑定事件的时候,是不是很怀念?ShadowDOM结构ShadowDOM允许隐藏的DOM树附加到常规DOM树上——它以Shadow根节点作为根节点开始,在这个根节点的底部可以是任何元素,就像普通的DOM元素一样,借用图片来自网络:下面是我根据自己的理解画的:大家可以根据自己的喜好看哪个更容易理解。你看哪一个都没关系。对应到实际的文档,它的结构是这样的:在上面的结构图中,我们看到了几个比较陌生的名词,包括之前看到的“shadowroot”,都是ShadowDOM的名词。接下来,我将解释它们各自的含义。ShadowDOM术语ShadowhostShadowDOM附加到的常规DOM节点。ShadowtreeShadowDOM内部DOM树。ShadowboundaryShadowDOM边界。ShadowDOM结束的地方,常规DOM开始的地方。ShadowrootShadow树的根节点。用法附加ShadowDOM您可以使用Element.attachShadow()方法将ShadowDOM附加到指定元素并返回对ShadowRoot的引用。让hostEle=document.getElementById("myCard");让shadowroot=hostEle.attachShadow({mode:"open"});控制ShadowDOM你可以使用同样的方式操作ShadowDOM,就像操作常规DOM一样——比如添加子节点,设置属性,给节点添加自己的样式(比如通过element.style属性),或者向整个ShadowDOM添加样式(例如在