Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 等待customElement子元素呈现,以强制定位它们_Javascript_Web Component_Lit Element_Lit Html_Lit - Fatal编程技术网

Javascript 等待customElement子元素呈现,以强制定位它们

Javascript 等待customElement子元素呈现,以强制定位它们,javascript,web-component,lit-element,lit-html,lit,Javascript,Web Component,Lit Element,Lit Html,Lit,我有一个组件MyWrapper,它由左侧的流动文本和右侧的边距组成。在页边空白处有MarginElement组件,这些组件应与文本中的标记垂直对齐 从'lit'导入{html,css,LitElement}; 从“lit/decorators.js”导入{customElement,property}; @customElement('my-wrapper') 导出类MyWrapper扩展了LitElement{ 静态样式=css`:host{display:flex}` render(){ 返

我有一个组件
MyWrapper
,它由左侧的流动文本和右侧的边距组成。在页边空白处有
MarginElement
组件,这些组件应与文本中的
标记垂直对齐

从'lit'导入{html,css,LitElement};
从“lit/decorators.js”导入{customElement,property};
@customElement('my-wrapper')
导出类MyWrapper扩展了LitElement{
静态样式=css`:host{display:flex}`
render(){
返回html`

Lorem ipsum dolor sit amet,行政长官
临时性的劳动和工作都是不可能的。
我们的工作是最低限度的,我们的工作是实践性的
实验室是从一个普通消费者身上取下的
在卷曲的纤毛中的reprehenderit中的irure dolor。

一些注释 其他一些注释 `; } 已更新(){this.positionMargin()} 位置边距(){ const elements=this.shadowRoot.querySelectorAll('margin-element')) elements.forEach(el=>{ const relatedElement=this.shadowRoot.querySelector(`${el.relatedElementId}`) el.style.top=relatedElement.getBoundingClientRect().top+'px' }) } } @customElement('margin-element') 导出类MarginElement扩展了LitElement{ 静态样式=css`:host{位置:绝对;边框:1px实心红色;}` @属性({type:String,attribute:'related element id'})relatedElementId:String render(){return html``} }
我想在
MyWrapper
上的渲染完成后运行函数
positionMargin()
,但我知道调用
relatedElement.getBoundingClientRect()
margin元素本身必须渲染。查看文档
updated()
似乎是调用
positionMargin()
的最佳位置。然而,似乎此时还没有呈现子
s。因此,
getBoundingClientRect()
不可用


如何解决这个问题?

多亏了Lit团队的帮助(谢谢!),我才得以解决。解决方案是在解析
updateComplete
promise之前,等待子级渲染完成

这可以通过查询所有
子项并等待其相应的
更新完成
承诺来实现(另请参阅)

因此,一旦我添加了,上面的代码就可以工作了

异步getUpdateComplete(){ 等待super.getUpdateComplete(); const marginElements=Array.from(this.shadowRoot.querySelectorAll('margin-element'); 等待Promise.all(marginElements.map(el=>el.updateComplete)); 返回true; }

这是一个亮起的游乐场,当您返回一个
MarginElement
数组时,.

它可以正常工作,因为它会导致它们在当前渲染更新后启动自己的渲染生命周期,但它不可靠

您的主要问题是希望垂直对齐在DOM中偏离相对y位置,但x位置堆叠在右侧。堆叠意味着
要么需要使用某种流/网格布局,要么需要相互了解,这很快就会变得令人讨厌

相反,我会添加一个新的
元素,负责绝对定位它的子
,并替换

然后在
位置margin
函数中设置传递给它的数组

然后在
渲染
中,有一组标记可以绝对定位,如果在同一
顶部有两个标记
,则可以打开后续标记

比如:

render(){
返回html`

同侧阴唇。。。
纤毛。

此.positionMargin()}>位置! `; } 位置边距(){ const elements=this.shadowRoot.querySelectorAll('margin-element')) 常量mwp=[]; elements.forEach(el=>{ 常量markWithPos={ top:relatedElement.getBoundingClientRect().top, 文本:e.innerText }); this.marksWithPositions=mwp;//请注意,这需要是@property或@state }
然后在
中:

render(){
常量定位=[];
设x=0;
对于(此标记的常数m){
如果(m.top>x)
定位。推(m);
其他的
push({top:x,m.text});
x+=预期的体重;
}
返回html`
${positioned.map(p=>html`
${p.text}`)}
`;
}
或者,也可以使用
..)}>
等方法,在每个
呈现时触发事件


要非常小心,
的渲染不会导致布局更改,从而移动
元素,因为您很容易获得循环竞态条件。您可能希望在任何地方都显示宽度和高度,但如果不需要,您还需要调整窗口大小和滚动观察者。

感谢您花时间编写如此详尽的答案。在我真正理解了问题的真相之后,为改变这个问题道歉。我理解您所指的问题,但我认为检查职位是否可用的功能也可以在
positionMargin()
中实现。
render() {
    const positioned = [];
    let x = 0;
    for(const m of this.marks) {
        if(m.top > x)
            positioned.push(m);

        else 
            positioned.push({ top: x, m.text });

        x += expectedElementHeight;
    }

    return html`
<div class="margin">
    ${positioned.map(p => html`
    <margin-element style=${styleMap({top: p.top + 'px'})}>${p.text}</margin-element>`)}
</div>`;
}