shadow dom

来源:互联网 发布:搜达数据 编辑:程序博客网 时间:2024/06/06 17:04

什么是 Shadow DOM?

Shadow DOM 是一个 HTML 的新规范,其允许开发者封装自己的 HTML 标签、CSS 样式和 JavaScript 代码。Shadow DOM 以及我们以后将会讨论的一些技术,使得开发人员可以创建诸如<video> 这样自定义的一级标签。总的来说,这些新标签和相关的 API 被称为Web Components

Shadow DOM 为何这么重要?

如果你已经做过一段时间的网站开发,你可能听过 Bootstrap。Bootstrap 是一组 UI 组件的集合,使用它需要将一系列 CSS 样式、JS 脚本以及规定的 HTML 模式糅合在一起。以下这个例子展示了使用 Bootstrapnavabar 所需要编写的 HTML 结构:

<nav class="navbar navbar-default navbar-fixed-top" role="navigation">    <div class="navbar-header">    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex6-collapse">      <span class="sr-only">Toggle navigation</span>      <span class="icon-bar"></span>      <span class="icon-bar"></span>      <span class="icon-bar"></span>    </button>    <a class="navbar-brand" href="#">Brand</a>  </div>  <div class="collapse navbar-collapse navbar-ex6-collapse">    <ul class="nav navbar-nav">      <li class="active"><a href="#">Home</a></li>      <li><a href="#">About</a></li>      <li><a href="#">Contact</a></li>    </ul>  </div></nav>  

由于无法封装 Boostrap 的组件,因此你自己的 HTML 必须要和它文档上的保持一致。很多时候这就意味着你要从 Boostrap 的说明文档里把这一坨代码复制过来然后粘贴到你的项目中。尽管用这种方法也可以快速的构建页面,但这也意味着大部分的页面标签都不是你自己写的,你也没有深入了了解这些页面结构。这可能会导致各种潜在的小 bug,你也无法快速直观的分析自己的工作——因为你代码里都是一坨又一坨的模板。

再考虑一下这个情况:Boostrap 的 CSS 样式表有大约 6600 行那么多,这就意味着任何时候你都有可能一个不小心覆盖了一个至关重要的选择器,导致页面一部分样式崩坏。你的 JavaScript 代码也需要和 Bootstrap 的 JavaScript 代码共存,同时要小心的遵守它的使用方式,而不能擅自变更。


一个简单的例子:

<body>    <div class="my-widget"><pre name="code" class="javascript"><div class="widget">Hello, world!</div>  
<h1>我的组件的标题</h1> <p>一些组件的内容</p> </div> <div class="my-other-widget"> <h1>我的另一个组件的标题</h1> <p>一些另一个组件的内容</p> </div></body>
当 HTML 转化成 DOM,每个元素都会变成一个节点(node)。而一组互相嵌套的一组节点则被称为节点树(node tree)

Shadow DOM 的独特之处在于它允许我们创建自己的节点树,这种节点树被称为影子树(shadow trees)。影子树对其中的内容进行了封装,有选择性的进行渲染。这就意味着我们可以插入文本、重新安排内容、添加样式等等。举个栗子:

<pre name="code" class="javascript"><script>      var host = document.querySelector('.widget');    var root = host.createShadowRoot();    root.textContent = '我在你的 div 里!';</script> 

通过上面的代码,我们已经通过一个影子树替换掉了我们 .widget div 的文本内容。要创建一个影子树,我们首先要指定一个节点担任影子宿主(shadow host)。在这个例子里,我们将.widget 当做我们的影子宿主。然后我们给影子宿主添加一个称作影子根(shadow root)的新节点。影子根作为影子树的第一个节点,其他的节点都是它的子节点。

如果你使用 Chrome 开发者工具检查这个元素,你会看到下面这样的结构:

看到 #shadow-root 是怎么被标灰显示的吗?这就是我们刚才创建的影子根。结果表明,影子宿主里面的内容没有被渲染,反而影子根里面的内容被渲染了出来。

这就是当实例运行时,我们看到 Im inside yr div! 而不是 Hello, world! 的原因。

ps:我的理解:比如input的各种类型:range number date 、audio这些,我们通过type的设置,标签的引入,便会有各自对应的样式,这些都是由于前辈们对这些进行过封装,使其达到这样的效果。封装的办法是shadow dom (影子树)影子树可以使内部的元素的样式与外部的相互不影响。保证了页面样式的不混乱。并且常规的CSS选择器并不能获取到shadow DOM子树,但也可以通过一些伪类元素来取得,从而可以改变他们本来的样式,比如input type="radio"默认的圆圈的样式,我们这时就可以通过取得影子树中的元素,修改其为方块的样子。不知道我理解的对不对,不对的地方请指出,谢谢


参考地址:http://www.ituring.com.cn/article/177461

http://mobile.51cto.com/web-440530.htm



0 0
原创粉丝点击