当我将 Shadow DOM 添加到自定义元素时......已经声明的非阴影内容(Light DOM)会消失到哪里?
When I add Shadow DOM to a custom element... where does the already declared non-shadow content (Light DOM) disappear to?
TLDR: 一旦我 define()
一个 自定义元素 与 影子 DOM,在同一元素中声明的 Light DOM 将从浏览器视口中消失。
为什么 Light DOM 在 Custom Element 中不再显示?
我正在学习/试验 Custom Elements
和 Shadow DOM
。
我注意到如果我有以下 Custom Element
而没有 任何 Shadow DOM
,它会起作用:
<my-company>© 2020, </my-company>
但是如果我 然后 通过 Shadow Dom
...
添加自定义内容到 Custom Element
class myCompany_Element extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
connectedCallback() {
this.root.textContent += 'Cyberdyne Systems';
}
}
customElements.define('my-company', myCompany_Element);
<my-company>© 2020, </my-company>
原始硬编码内容消失。 (即使它在 DOM 检查器中仍然可见。)
我期待:
© 2020, Cyberdyne Systems
这里发生了什么?
这是否意味着不可能
- a
Custom Element
有 和 没有 Shadow DOM
而且我只能有:
- 一个
Custom Element
没有Shadow DOM
- a
Custom Element
与 Shadow DOM
和 slots
或者 Custom Element
有 和 没有 Shadow DOM
是可能的吗?
据我的实验和进一步阅读可以看出,这就是正在发生的事情:
通过在 class
定义中调用 attachShadow()
,我们明确确定元素 将 成为 Shadow Host
当它是 define()
-d:
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
一旦元素正式成为 Shadow Host
其 Light DOM 将不再显示在视口中:
-
Shadow Host
将不会显示 Light DOM 已经在 HTML 中声明
Shadow Host
将不会显示 Light DOM 稍后添加,通过 Javascript
进一步确认:
By default, if an element has shadow DOM, the shadow tree is rendered
instead of the element's children
Source: https://polymer-library.polymer-project.org/3.0/docs/devguide/shadow-dom
结论:
恢复元素的 Light DOM 子元素的标准(也是唯一的?)方法是使用命名 <slot>
-s,在此案例:
class myCompany_Element extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
connectedCallback() {
this.root.innerHTML += '<slot name="template"></slot>';
this.root.innerHTML += 'Cyberdyne Systems';
}
}
customElements.define('my-company', myCompany_Element);
<my-company><span slot="template">© 2020, </span></my-company>
这是一个不需要 slot
s 的适用于您的用例的简单解决方案:
class myCompany_Element extends HTMLElement {
constructor() {
super()
this.root = this.attachShadow({ mode: 'open' })
}
connectedCallback() {
// added line below
this.root.textContent += this.textContent
this.root.textContent += 'Cyberdyne Systems'
}
}
customElements.define('my-company', myCompany_Element)
<my-company>© 2020, </my-company>
如果需要,您也可以在设置 this.root.textContent
后将 this.textContent
归零为 ''
。据我所知,使用 Chrome 开发工具,这样做对可访问性没有影响,但从开发人员体验的角度来看可能是可取的。
TLDR: 一旦我 define()
一个 自定义元素 与 影子 DOM,在同一元素中声明的 Light DOM 将从浏览器视口中消失。
为什么 Light DOM 在 Custom Element 中不再显示?
我正在学习/试验 Custom Elements
和 Shadow DOM
。
我注意到如果我有以下 Custom Element
而没有 任何 Shadow DOM
,它会起作用:
<my-company>© 2020, </my-company>
但是如果我 然后 通过 Shadow Dom
...
Custom Element
class myCompany_Element extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
connectedCallback() {
this.root.textContent += 'Cyberdyne Systems';
}
}
customElements.define('my-company', myCompany_Element);
<my-company>© 2020, </my-company>
原始硬编码内容消失。 (即使它在 DOM 检查器中仍然可见。)
我期待:
© 2020, Cyberdyne Systems
这里发生了什么?
这是否意味着不可能
- a
Custom Element
有 和 没有Shadow DOM
而且我只能有:
- 一个
Custom Element
没有Shadow DOM
- a
Custom Element
与Shadow DOM
和slots
或者 Custom Element
有 和 没有 Shadow DOM
是可能的吗?
据我的实验和进一步阅读可以看出,这就是正在发生的事情:
通过在 class
定义中调用 attachShadow()
,我们明确确定元素 将 成为 Shadow Host
当它是 define()
-d:
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
一旦元素正式成为 Shadow Host
其 Light DOM 将不再显示在视口中:
-
Shadow Host
将不会显示 Light DOM 已经在 HTML 中声明
Shadow Host
将不会显示 Light DOM 稍后添加,通过 Javascript
进一步确认:
By default, if an element has shadow DOM, the shadow tree is rendered instead of the element's children
Source: https://polymer-library.polymer-project.org/3.0/docs/devguide/shadow-dom
结论:
恢复元素的 Light DOM 子元素的标准(也是唯一的?)方法是使用命名 <slot>
-s,在此案例:
class myCompany_Element extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
connectedCallback() {
this.root.innerHTML += '<slot name="template"></slot>';
this.root.innerHTML += 'Cyberdyne Systems';
}
}
customElements.define('my-company', myCompany_Element);
<my-company><span slot="template">© 2020, </span></my-company>
这是一个不需要 slot
s 的适用于您的用例的简单解决方案:
class myCompany_Element extends HTMLElement {
constructor() {
super()
this.root = this.attachShadow({ mode: 'open' })
}
connectedCallback() {
// added line below
this.root.textContent += this.textContent
this.root.textContent += 'Cyberdyne Systems'
}
}
customElements.define('my-company', myCompany_Element)
<my-company>© 2020, </my-company>
如果需要,您也可以在设置 this.root.textContent
后将 this.textContent
归零为 ''
。据我所知,使用 Chrome 开发工具,这样做对可访问性没有影响,但从开发人员体验的角度来看可能是可取的。