我正在尝试使用CSS更改HTML页面上的元素,然后立即读取其可视属性。然而,CSS强制样式直到稍后(下一个'帧')才会应用。
CSS:
.node {
width: 10px;
}
JavaScript的:
// Create element
var element = document.createElement("div");
element.className = "node";
document.body.appendChild(element);
console.log(element.clientWidth);
上面的log
调用的输出应为10
,但如果立即调用则为NaN
(但在帧后正确读取为10
)。< / p>
使用getComputedStyle()
会得到类似的结果:
var style = getComputedStyle(element);
console.log(element.style);
首次运行时输出为“”,第一帧后输出为“10px”(正确)。
我假设我必须等待一次浏览器的重新布局,直到我可以阅读该属性。有没有办法强制浏览器计算该元素的维度?或许这可能是不好的做法;有没有直接的方法来读取CSS的宽度属性?
换句话说,这里的最佳做法是什么?
注意:尽量避免在这里使用jQuery或其他库。
答案 0 :(得分:2)
尝试改为访问computedStyle
。
var computedStyle = document.defaultView ? document.defaultView.getComputedStyle(element, null) : element.currentStyle;
然后阅读
console.log( computedStyle.width);
答案 1 :(得分:1)
你说对,浏览器必须先执行重排才能确定更改后的属性的效果(从而读取更改后的值)。我相信你知道,JavaScript是由浏览器的内部事件循环执行的。直到当前事件的JS代码完全执行后 之后才会执行重排。
要解决您的问题,您可以使用setImmediate()
。这允许您对要尽快处理的新事件进行排队。你基本上“屈服”,允许重排发生,然后跳回来完成剩下的代码:
var element = document.createElement("div");
element.className = "node";
document.appendChild(element);
setImmediate(function() {
console.log(element.clientWidth);
});
请注意,截至目前,很少有流行的浏览器支持setImmediate
。要解决此问题,您可以使用setTimeout
延迟0
:
setTimeout(function() {
console.log(element.clientWidth);
}, 0);
以下是一个工作示例:jsbin.com/ehigor
还要记住,在setTimeout
块之后放置的任何代码都将在块内部的代码之前执行,在当前“帧”结束之前执行,因此在重排之前执行。
<强>更新强>
jAndy's answer是对的; getComputedStyle
将解决OP的问题。在这种情况下,不需要重排,因为您要做的就是读取设置的CSS属性。
这需要getComputedStyle
的原因是因为未在JavaScript中设置样式规则。与element.style
不同,getComputedStyle
会考虑外部CSS文件中设置的样式规则以及浏览器的默认样式规则。
有些情况下,getComputedStyle
不足够,并且需要重排 :当样式规则的值与实际不直接相关时,风格的最终价值。最值得注意的案例是相对维度和位置。如果您将width
设置为(例如)50%
,但想要以像素读取元素的宽度,则只能通过让它来查找该值的值浏览器执行重排(在这种情况下setTimeout
很有用)。另一方面,如果您想知道width
设置为"50%"
;使用getComputedStyle
。
答案 2 :(得分:-1)
在检查宽度之前,可能使用setTimeout等待半秒钟?