参考网站
MDN Web Docs - Using shadow DOM
An important aspect of web components is encapsulation — being able to keep the markup structure, style, and behavior hidden and separate from other code on the page so that different parts do not clash, and the code can be kept nice and clean. The Shadow DOM API is a key part of this, providing a way to attach a hidden separated DOM to an element. This article covers the basics of using the Shadow DOM.
web components 的其中一个重要的部分是封装 -- 可以保持 指定的结构,样式和行为与页面的不同的部分隐藏和分开而避开冲突, 代码可以保持简洁和良好。 Shadow DOM Api 是一个封装的关键部分,它提供了一种方法使一个隐藏的DOM绑定到element中。 这编文章全面地介绍 Shadow DOM 的基础。
This article assumes you are already familiar with the concept of the DOM (Document Object Model) — a tree-like structure of connected nodes that represents the different elements and strings of text appearing in a markup document (usually an HTML document in the case of web documents). As an example, consider the following HTML fragment:
这编文章假设你已经熟悉DOM的概念 - 一个树状结构连结不同的element/text出现在指定的标签的元素node(通常一个HTML 元素在一个web documents中)。 作为一个例子, 请看下面的HTML 片段.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simple DOM example</title>
</head>
<body>
<section>
<img src="dinosaur.png" alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.">
<p>Here we will add a link to the <a href="https://www.mozilla.org/">Mozilla homepage</a></p>
</section>
</body>
</html>
Shadow DOM allows hidden DOM trees to be attached to elements in the regular DOM tree — this shadow DOM tree starts with a shadow root, underneath which can be attached to any elements you want, in the same way as the normal DOM.
Shadow DOM 允许隐藏dom trees 来挂载元素到一个常规的dom trees - shadow Dom tree 顶端是一个shadow root 根元素,根元素下面可以像一个普通元素一样可以挂载所有你想挂载的元素
There are some bits of shadow DOM terminology to be aware of:
- Shadow host: The regular DOM node that the shadow DOM is attached to.
- Shadow tree: The DOM tree inside the shadow DOM.
- Shadow boundary: the place where the shadow DOM ends, and the regular DOM begins.
- Shadow root: The root node of the shadow tree.
这里需要注意一个关于shadow dom 的术语;
- Shadow host: 那个被shadow dom 挂载中的普通的dom;
- Shadow tree: 在shadow dom 中的 dom tree;
- Shadow boundary: shodow dom 的结束点和 普通dom 的开始点;
- Shadow root: shadow tree 的根节点;
You can affect the nodes in the shadow DOM in exactly the same way as non-shadow nodes — for example appending children or setting attributes, styling individual nodes using element.style.foo, or adding style to the entire shadow DOM tree inside a element. The difference is that none of the code inside a shadow DOM can affect anything outside it, allowing for handy encapsulation.
你可以操控shadow DOM 中的元素,就像操作非shadow 元素一样。 例如添加子元素或者修改attributes,使用element.style.foo 为单独元素修改样式。或者在一个元素中为整个shadow DOM tree 添加样式。不同的是所有在shadowDom中的元素不能影响到外面,允许更容易地封装。
Note that the shadow DOM is not a new thing by any means — browsers have used it for a long time to encapsulate the inner structure of an element. Think for example of a element, with the default browser controls exposed. All you see in the DOM is the element, but it contains a series of buttons and other controls inside its shadow DOM. The shadow DOM spec has made it so that you are allowed to actually manipulate the shadow DOM of your own custom elements.
记住shadow DOM 不是新的事物,事实上,浏览器已经使用它来封装内置结果的元素很多的一段时间了。举个例子 元素, 它包含了一系列的按钮和其它控制元素在里面。Shadow DOM 规范已经做到了这一点,所以你可以操作你自定义的shadow DOM
Basic usage 基本使用
You can attach a shadow root to any element using the Element.attachShadow() method. This takes as its parameter an options object that contains one option — mode — with a value of open or closed
你可以使用Element.attachShadow() 方法在任何一个element中挂载一个shadow root。这个方法带有一个可选的object, 这个参数 包含一个选项 mode, 这个参数的取值是open / close;
let shadow = elementRef.attachShadow({mode: 'open'}); open means that you can access the shadow DOM using JavaScript written in the main page context, for example using the Element.shadowRoot property: open 则表示你可以在主页面内容中使用javascript 获取shadow Dom. 例如使用Element.shadowRoot 这个特性;
let shadow = elementRef.attachShadow({mode: 'closed'});
If you attach a shadow root to a custom element with mode: closed set, you won't be able to access the shadow DOM from the outside — myCustomElem.shadowRoot returns null. This is the case with built in elements that contain shadow DOMs, such as .
如果你使用mode : close 来挂载一个自定义元素的shadow dom , 你将不能在外面获取到shadow DOM, myCustomElem.shadowRoot 会返回空。 这个就像内置元素一样的shadow DOM,例如