考虑以下test-element
Web 组件定义(在 Google Chrome 上运行的原生 JavaScript,而不是 Polymer),它创建了一个简单的width=500px
. 它的attachedCallback
函数将其宽度输出到控制台,然后设置一个异步延迟再次执行此操作:
测试元素.html
<style> test-element { display: inline-block; width: 500px; } </style>
<script>
(function (window, document) {
var proto = Object.create(HTMLElement.prototype);
proto.attachedCallback = function () {
// Direct output.
console.log("(1) test-element.width = ", this.offsetWidth);
// Delayed output.
window.setTimeout(function () { console.log("(2) test-element.width = ", this.offsetWidth); }.bind(this), 0);
};
document.registerElement('test-element', {prototype: proto});
})(window, document);
</script>
然后我创建一个导入的页面test-element
,并再次从内联脚本标签输出其宽度:
索引.html
<!DOCTYPE html>
<html>
<head>
<link rel="import" href="test-element.html">
</head>
<body>
<test-element></test-element>
<script>
var testElement = document.querySelector('test-element');
console.log("(3) test-element.width = ", testElement.offsetWidth);
</script>
</body>
</html>
控制台的输出是:
(1) test-element.width = 0
(3) test-element.width = 500
(2) test-element.width = 500
这证明attachedCallback
(1) 在布局和绘制之前被调用,有时这确实是我想要的。例如,如果我想将其宽度更改为 100 像素,我可以 make testElement.style.width = "100px"
,并且我不必担心组件在回调有机会进行更改之前闪烁其先前的 500px 宽度。
但是,attachedCallback
有时在布局之前被调用并不是我想要的。例如,如果test-element
包含一个网格,并且它需要绘制单元格,那么我需要知道它的宽度,以便我可以计算有多少单元格适合可用空间。但是我在 期间没有这些信息attachedCallback
,我似乎无法掌握如何获取这些信息。
如您所见,在这个非常简单的示例中,0ms 延迟 (2) 似乎触发了布局计算。但是一旦我开始做更复杂的事情(例如当我有嵌套的 Web 组件和异步 HTML 导入时),0ms 延迟是不够的,我必须将其更改为 100ms 延迟,然后更多。
我的问题是:如何尽快可靠地获得组件的宽度(或任何其他计算样式)?