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