# 影子 DOM(Shadow DOM) Shadow DOM 为封装而生。它可以让一个组件拥有自己的「影子」DOM 树,这个 DOM 树不能在主文档中被任意访问,可能拥有局部样式规则,还有其他特性。 ## 内建 shadow DOM 你是否曾经思考过复杂的浏览器控件是如何被创建和添加样式的? 比如 ``:
浏览器在内部使用 DOM/CSS 来绘制它们。这个 DOM 结构一般来说对我们是隐藏的,但我们可以在开发者工具里面看见它。比如,在 Chrome 里,我们需要打开「Show user agent shadow DOM」选项。 然后 `` 看起来会像这样:  你在 `#shadow-root` 下看到的就是被称为「shadow DOM」的东西。 我们不能使用一般的 JavaScript 调用或者选择器来获取内建 shadow DOM 元素。它们不是常规的子元素,而是一个强大的封装手段。 在上面的例子中,我们可以看到一个有用的属性 `pseudo`。这是一个因为历史原因而存在的属性,并不在标准中。我们可以使用它来给子元素加上 CSS 样式,像这样: ```html run autorun ``` 重申一次,`pseudo` 是一个非标准的属性。按照时间顺序来说,浏览器首先实验了使用内部 DOM 结构来实现控件,然后,在一段时间之后,shadow DOM 才被标准化来让我们,开发者们,做类似的事。 接下来,我们将要使用现代 shadow DOM 标准,它在 [DOM spec](https://dom.spec.whatwg.org/#shadow-trees) 和其他相关标准中可以被找到。 ## Shadow tree 一个 DOM 元素可以有以下两类 DOM 子树: 1. Light tree(光明树) —— 一个常规 DOM 子树,由 HTML 子元素组成。我们在之前章节看到的所有子树都是「光明的」。 2. Shadow tree(影子树) —— 一个隐藏的 DOM 子树,不在 HTML 中反映,无法被察觉。 如果一个元素同时有以上两种子树,那么浏览器只渲染 shadow tree。但是我们同样可以设置两种树的组合。我们将会在后面的章节