我有两个 Lit-element Web 组件 - 一个是units-list
,其中包含许多units-list-item
元素。这units-list-item
元素有两种不同的显示模式:紧凑和详细。由于列表元素支持无限滚动(因此可能包含数千个单元),因此我们需要在两种模式之间切换的任何机制,以尽可能提高性能。
这就是为什么我认为理想的解决方案是使用:host-context()
样式中的伪选择器units-list-item
元素,这样每个units-list-item
元素可以在两种显示模式之间切换,只需更改应用于祖先的类(该类将位于该元素的影子 DOM 内)units-list
元素)。
为了详细说明,这里是来自units-list
元素。请注意,“触发”类被应用于#list-contents
div,它是units-list
模板。
<div id="list-contents" class="${showDetails ? 'detail-view table' : 'compact-view table'}">
${units.map(unit => html`<units-list-item .unit="${unit}"></units-list-item>`)}
</div>
如您所见,showDetails
flag 控制是否将“detail-view”或“compact-view”类应用于包含所有内容的 divunits-list-item
元素。这些课程肯定被正确应用。
这是完整的渲染方法units-list-item
元素(删除不必要的标记):
render() {
const {unit} = this;
// the style token below injects the processed stylesheet contents into the template
return html`
${style}
<div class="row compact">
<!-- compact row markup here -->
</div>
<div class="row detail">
<!-- detail row markup here -->
</div>
`;
}
然后我有以下内容units-list-item
元素的样式(我们使用 SCSS,因此单行注释不是问题):
// This SHOULD hide the compact version of the row when the
// unit list has a "detail" class applied
:host-context(.detail-view) div.row.compact {
display: none !important;
}
// This SHOULD hide the detail version of the row when the
// unit list has a "compact" class applied
:host-context(.compact-view) div.row.detail {
display: none !important;
}
我对 :host-context 选择器的理解表明这应该有效,但 Chrome 每次都会渲染该行的两个版本,并且 Chrome 开发工具显示选择器永远不会与任何一行匹配。
我知道有几种可行的替代方案,但这是我所知道的唯一一种可以通过更改父元素上的单个类来允许整个单元列表切换模式的方案。我考虑过的所有其他解决方案至少都需要更新每个units-list-item
列表中的元素。如果可能的话我想避免这种情况。
当然,我主要关心的是如果可能的话,让这项工作可行,但我也对一些事情感到好奇,但找不到有关它们的任何信息。我似乎找不到答案的两个问题是
- When
:host-context
在本身就是影子 DOM 一部分的元素中使用,它是否认为父元素的影子 DOM 是“主机上下文”,或者它是否“一路跳出”到文档 DOM?
- 如果是前者的话,会
:host-context
跳转多个 Shadow DOM 边界?说我有一个习惯page
包含自定义的元素list
元素,它本身包含许多自定义item
元素。其中item
元素有一个:host-context
规则,浏览器会首先扫描 Shadow DOMlist
元素,然后,如果没有匹配任何内容,则扫描该元素的影子 DOMpage
元素,如果仍然没有匹配任何内容,则将主文档 DOM 扫描到<html>
tag?