1

我正在尝试使用 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在一帧之后)。

使用getComputedStyle()给出了类似的结果:

var style = getComputedStyle(element);
console.log(element.style);

首次运行时输出为“”,但在第一帧之后为“10px”(正确)。

我假设我必须等待一次浏览器的重新布局,直到我可以读取该属性。有没有办法强制浏览器计算该元素的尺寸?或者那可能是不好的做法;有没有一种简单的方法来读取 CSS 的 width 属性?

换句话说,这里的最佳做法是什么?

注意:这里尽量避免使用 jQuery 或其他库。

4

3 回答 3

2

尝试访问computedStyle

var computedStyle = document.defaultView ? document.defaultView.getComputedStyle(element, null) : element.currentStyle;

然后阅读

console.log( computedStyle.width);

示例:http: //jsfiddle.net/mGCT5/1/

于 2012-07-12T14:10:49.737 回答
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的回答是对的;getComputedStyle将解决OP的问题。在这种情况下,不需要重排,因为您要做的就是读取设置的 CSS 属性。

之所以getComputedStyle需要这样做是因为样式规则没有在 JavaScript 中设置。与 不同element.stylegetComputedStyle将考虑在外部 CSS 文件中设置的样式规则以及浏览器的默认样式规则。

有些情况getComputedStyle不够,需要重排:当样式规则的值与样式的实际最终值不直接相关时。最值得注意的情况是相对尺寸和位置。如果您设置width为 (例如) 50%,但您想读取元素的宽度(以像素为单位),您只能通过让浏览器执行重排来找出该值是多少(在这种情况下setTimeout很有用)。另一方面,如果您想知道width设置为"50%"; 使用getComputedStyle.

于 2012-07-12T14:33:27.360 回答
-1

也许在检查宽度之前使用 setTimeout 等待半秒?

于 2012-07-12T14:08:06.427 回答