Web组件offsetHeight / offsetWidth连接时为零

时间:2019-06-18 12:14:30

标签: javascript html web-component

我正在尝试将我的库转换为Web组件,并且遇到了何时告诉组件已布置的问题。

Web组件有一个名为connectedCallback的回调,看起来可能是我需要的回调,但是在回调中检查self时,我的偏移量均为零:

connectedCallback() {
  console.log(this.offsetWidth, this.offsetHeight);
}

当我在尺寸查询中排队时,尺寸就在那里,因此在Web组件连接到事件队列到达下一项之间的某个时间,Web组件被浏览器引擎布局,获得正确的尺寸值:

connectedCallback() {
  setTimeout(() => console.log(this.offsetWidth, this.offsetHeight), 0);
}

我想知道是否有一个回调来告诉布局事件何时发生?

2 个答案:

答案 0 :(得分:2)

我创建了一个没有shadowDOM的简单组件。我在构造函数中编写了以下代码:

this.addEventListener('readystatechange', (evt) => {console.log('readystatechange', evt)});
this.addEventListener('load', (evt) => {console.log('load', evt)});
this.addEventListener('progress', (evt) => {console.log('progress', evt)});
this.addEventListener('DOMContentLoaded', (evt) => {console.log('DOMContentLoaded', evt)});

没有任何输出。因此,这些事件都不会在Web组件上触发。

然后我将此代码添加到组件之外:

function callback(mutationsList, observer) {
  for(var mutation of mutationsList) {
    if (mutation.type === 'childList') {
      if (mutation.removedNodes.length) {
        console.log(`${mutation.removedNodes.length} child node(s) have been removed.`);
      }

      if (mutation.addedNodes.length) {
        console.log(`${mutation.addedNodes.length} child node(s) have been added.`);
      }
    }
  }
}
var config = { childList: true };
var observer = new MutationObserver(callback);

这行到构造函数:

observer.observe(this, config);

在我的特定组件上,从未调用过callback

我确实有一个不同的组件来更改其子代,并调用了回调。

因此,我看不到任何事件或什至在组件完全加载时触发的突变观察器。

我个人会像您一样使用setTimeout,因为这似乎是在组件完成后获得呼叫的唯一肯定的方法。尽管您可能必须具体说明放置setTimeout的位置,以确保完全呈现DOM。

答案 1 :(得分:2)

这些值取决于整个DOM,因此需要重新绘制DOM。 尚未发生

如果每个元素都会触发DOM重绘,我们都会抱怨性能。

浏览器决定(浏览器特定的逻辑)何时进行DOM重绘。

在重绘DOM后常用的执行代码的方法是 public string ToPhonetic(string source) { var sb = new StringBuilder(); foreach (var ch in source.ToUpper()) { switch (ch) { case 'A': sb.Append("Alpha, "); break; case 'B': sb.Append("Bravo, "); break; default: sb.Append(ch); break; } } return sb.ToString(); }

因此严格来说,这不会强制重绘DOM,仍然由浏览器决定何时重绘
如果您的脚本运行时间较长...... FUNC将在完成
脚本后执行

是的,活动会很好...
但这需要占用CPU周期...在1000个案例中有997个不需要信息
..因此,没有事件

因此,在您需要DOM信息的情况下,有0,03%的情况下,您需要进行setTimeout( FUNC , 0 )

请注意,这并非特定于“自定义元素”,对于setTimeout调用同样适用。

如果您有大量需要此偏移量信息的组件,则可能希望查看一个进行虚拟DOM区分的框架

更多背景:Medium: What the heck is repaint/reflow (2019)