Shadow DOM 模式
Open模式
你是否在上述 attachShadow()
方法里注意到 {mode: "open"}
配置? open
模式提供了一种我们可以通过JavaScript来访问元素的shadow DOM的方式,这种模式也允许我们通过shadow DOM来访问宿主元素。
这是通过我们在 open
模式下使用 attachShadow()
时候创建的两个隐式属性来实现的。
- 被创建元素获得了一个叫做
shadowRoot
的属性,该属性指向了shadow DOM; shadowRoot
获得了一个叫做host
的属性,该属性指向该元素本身;
// From the "How to create shadow DOM" example
el.attachShadow({ mode: 'open' });
// Just like prototype & constructor bi-directional references, we have...
el.shadowRoot; // the shadow root.
el.shadowRoot.host; // the el itself.
Closed 模式
将 {mode: "closed"}
传递给 attachShadow()
,来创建一个闭合的shadow DOM。该操作使得JavaScript无法访问shadow DOM。
el.shadowRoot; // null
应该选择哪种模式?
几乎大部分场景下使用open
模式的shadow DOMs ,因为这种模式可以让组件开发者和使用者能够按照他们的需求去做些事情。
还记得我们做过 el.shadowRoot
那部分么?在 closed
模式下,是不生效的。closed
模式使得元素不会有对本身shadow DOM的引用。当在创建一个元素并想要通过shadow DOM 进行一些操作时候,closed
模式会造成阻碍。
class CustomPicture extends HTMLElement {
constructor() {
this.attachShadow({ mode: 'open' }); // this.shadowRoot exists. add or remove stuff in there using this ref.
this.attachShadow({ mode: 'closed' }); // this.shadowRoot returns null. Bummer!
}
}
// You could always do the following in your constructor.
// but it totally defies the purpose of using closed mode.
this._shadowRoot = this.attachShadow({ mode: 'closed' });
此外,封闭模式不是一种安全的机制。他只是给人一种虚假的安全感。没有人可以阻止其他人修改 Element.prototype.attachShadow()
。