:host-context 在 Lit-Element Web 组件中没有按预期工作 [英] :host-context not working as expected in Lit-Element web component

查看:64
本文介绍了:host-context 在 Lit-Element Web 组件中没有按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个 Lit 元素 Web 组件 - 一个是 units-list,它包含许多 units-list-item 元素.units-list-item 元素有两种不同的显示模式:紧凑和详细.由于列表元素支持无限滚动(因此可能包含数千个单位),我们需要任何能够在两种模式之间切换的机制以尽可能提高性能.

I've got two Lit-element web components - one is units-list, which contains many units-list-item elements. The units-list-item elements have two different display modes: compact and detailed. Because the list element supports infinite scroll (and thus could contain several thousand units), we need any mechanism that toggles between the two modes to be as performant as possible.

这就是为什么我认为理想的解决方案是在 units-list-item 元素的样式中使用 :host-context() 伪选择器,这样,每个 units-list-item 元素都可以在两种显示模式之间切换,只需更改应用于祖先的类(位于 units-list 元素).

That's why I thought an ideal solution would be to use the :host-context() pseudo-selector in the styles for the units-list-item element, as that way every units-list-item element could switch between the two display modes just by changing the class applied to an ancestor (which would be within the shadow DOM of the units-list element).

详细说明,这里是来自 units-list 元素的相关标记.请注意,触发器"类被应用于 #list-contents div,它是 units-list 模板的一部分.

To elaborate, here's the relevant markup from the units-list element. Note that the "trigger" classes are being applied to the #list-contents div, which is part of the units-list template.

<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>
${units.map(unit => html`<units-list-item .unit="${unit}"></units-list-item>`)}

As you can see, the showDetails flag controls whether the "detail-view" or "compact-view" class is applied to the div containing all of the units-list-item elements. Those classes are definitely being applied correctly.

如您所见,showDetails 标志控制是将detail-view"还是compact-view"类应用于包含所有 units-list-item 的 div 元素.这些课程肯定被正确应用.

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 元素的完整渲染方法(删除了不必要的标记):

Then I have the following in the units-list-item element's styles (we're using SCSS, so the single-line comments are not a problem):

    // 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;
    }

<div class="行细节"><!-- 此处详细行标记-->

My understanding of the :host-context selector says that this should work, but Chrome just renders both versions of the row every time, and the Chrome dev tools show that the selectors are never matching with either of the rows.

`;}

然后我在 units-list-item 元素的样式中有以下内容(我们使用的是 SCSS,所以单行注释不是问题):

Of course, my primary concern is simply to make this work, if possible, but I'm also curious about a couple of things and can't find any info about them. The two questions I can't seem to find an answer for are


  • When :host-context is used within an element that is itself part of a shadow DOM, does it consider that parent element's shadow DOM to be the "host context", or does it jump "all the way out" to the document DOM?
  • If it's the former, will :host-context jump multiple shadow DOM boundaries? Say I have a custom page element that contains a custom list element, which itself contains many custom item elements. If that item element has a :host-context rule, will the browser first scan up the shadow DOM of the list element, then, if matching nothing, scan up the shadow DOM of the page element, and if still matching nothing, then scan up the main document DOM to the <html> tag?
  • 我对 :host-context 选择器的理解表明这应该可以工作,但 Chrome 每次只呈现行的两个版本,Chrome 开发工具显示选择器永远不会与任何一行匹配.

    我知道有几种可行的替代方法,但这是我所知道的唯一一种可以通过更改父元素上的单个类来允许整个单元列表切换模式的方法.我考虑过的所有其他解决方案都至少需要更新列表中每个 units-list-item 元素上的 class 属性.如果可能,我想避免这种情况.

    当然,如果可能的话,我的主要关注点只是让这项工作顺利进行,但我也对一些事情感到好奇,但找不到有关它们的任何信息.我似乎找不到答案的两个问题是

    解决方案
    1. :host-context 用在一个本身是 shadow DOM 一部分的元素中时,它是否认为父元素的 shadow DOM 是宿主上下文",或者它是否会跳转一直到到文档 DOM?
    2. 如果是前者,:host-context 会跳过多个 shadow DOM 边界吗?假设我有一个包含自定义 list 元素的自定义 page 元素,该元素本身包含许多自定义 item 元素.如果那个 item 元素有一个 :host-context 规则,浏览器是否会先扫描 list 元素的 shadow DOM,然后,如果不匹配,扫描page元素的shadow DOM,如果仍然不匹配,则扫描主文档DOM到标签?立>

    推荐答案

    FireFox 或 Safari 不支持 :host-context

    <块引用>

    一个月前的最后一次更新是 Mozilla 和 Apple 都不会实施它.

    Looks like it is going to be removed from the spec: https://github.com/w3c/csswg-drafts/issues/1914

    <块引用>

    看起来它将从规范中删除:https://github.com/w3c/csswg-drafts/issues/1914

    <块引用>

    另一种选择是使用 CSS 属性(这些属性会渗透到shadowDOM)

    One alternative is to use CSS Properties (those trickle down into shadowDOM)

    JSFiddle:https://jsfiddle.net/CustomElementsExamples/jb6c81ou/

    • 为 Chrome 和 Edge 使用 host-context
    • 为其他浏览器使用 CSS 属性
    • 这篇关于:host-context 在 Lit-Element Web 组件中没有按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆