【问题标题】:Lit-element - :host selector is not triggering render on SafariLit-element - :host 选择器未在 Safari 上触发渲染
【发布时间】:2021-06-21 15:01:51
【问题描述】:

在我正在进行的一个项目中,我有这个 LitElement 组件,它是绝对定位,并根据其反应属性确定其左侧或顶部位置。

我只在 Safari 中遇到了问题,包括 iOS Safari/Chrome/Firefox。该元素已更新其阴影样式,但在视图中它根本没有移动。当我发现当光标悬停在元素上,或退出浏览器视图时,元素会弹出到预期的位置时,我意识到这是一个渲染问题。

我设法用更简单的代码重现了这个问题:

my-elem.ts:

import { LitElement, html, property, customElement, css } from 'lit-element';

@customElement('my-elem')
export class MyElem extends LitElement {
    @property({ type: Number, reflect: true })
    left: number = 30

    static get styles() {
        return css`
            :host { position: absolute; }
            div { position: absolute; }
        `;
    }

    render() {
        return html`
            <style>
                :host { left: ${this.left}px; }
            </style>
            <div> Hello </div>
        `;
    }
}

index.html:

<html lang="en">
<head>
  <script src="my-elem.ts"></script>
</head>
<body>
    <my-elem id="my-elem" left="50"></my-elem>
    <button id="move-btn">move</button>
    <script>
        const elem = document.getElementById('ma-elem');
        const moveBtn = document.getElementById('move-btn');
        moveBtn.onclick = function() {
            elem.left += 30;
        }
    </script>
</body>
</html>

我发现这只发生在:host 选择器上。如果阴影样式更新了divleft,它的渲染没有任何问题。

我希望避免由于性能问题而强制浏览器进行布局/绘制。

【问题讨论】:

    标签: css safari shadow-dom lit-element


    【解决方案1】:

    我认为您的问题的根源是您试图在渲染模板的样式元素中使用表达式。

    LitElement 指南提到以这种方式使用它们has limitations and can cause performance issues。我认为您的问题只是面临其中之一,因此您应该删除该样式元素。

    作为替代方案,由于您想影响宿主元素,如果您不使用属性而是直接设置宿主元素,则实际上可以以更简单的方式执行此操作。

    所以当使用my-elem 时,代码如下所示:

    <my-elem style="left: 30px;"></my-elem>
    

    这是因为在 shadow DOM 中应用于 :host 的样式的优先级低于使用类或其父级的样式属性应用于它的样式。

    或者,如果您真的想保留该属性,您可以create property accessorsleft 属性并从那里将样式设置为主机,如下所示:

    export class MyElem extends LitElement {
      // other code
      
      set left(value) {
        const oldValue = this.left;
        this._left = value;
        this.style.setProperty('left', `${value}px`)
        this.requestUpdate('left', oldValue);
      }
      
      get left() {
        return this._left;
      }
      
    }

    【讨论】:

    • 谢谢!我确实希望保留它,因为在实际代码中,左侧位置是使用其他数据计算的。
    • @SilberGuy 很好,请记住,对于特定类型的样式,使用属性并不总是必要的。在开发未来的组件时,这些知识可能会有所帮助?。顺便说一句,如果这个答案解决了你的问题,请考虑接受这个答案?
    猜你喜欢
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 2019-11-01
    • 2019-05-24
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多