强制浏览器在更改CSS时触发重排

时间:2014-02-09 20:56:39

标签: javascript html css css3 reflow

我正在构建基于CSS3过渡的非jQuery响应式图像滑块。

结构很简单:视口和内部相对定位的UL,左浮动LI。

在这种情况下我遇到了问题:

  1. 用户点击“上一页”箭头。
  2. JS在当前显示的LI节点之前附加适当的LI。
  3. 目前,UL已将CSS转换设置为none 0s linear以防止动画更改。在这一刻,我通过滑块宽度减去UL CSS左值(假设:从0px到-1200px),使视图与原来相同。
  4. 现在我将UL的过渡属性更改为all 0.2s ease-out
  5. 现在我正在更改UL的左侧属性以触发CSS3动画。 (比方说:从-1200px到0px)。
  6. 有什么问题?浏览器简化了更改,不会制作任何动画。

    Stoyan Stefanov在他的博客here上写了一篇关于回流问题的文章,但是在这种情况下,试图强制对元素进行重排不起作用。

    这是一段代码(为了简化我省略了浏览器前缀):

    ul.style.transition = 'none 0s linear 0s'; ul.style.left = '-600px'; ul.style.transition = 'all 0.2s ease-out'; ul.style.left = '0px';

    以下是查看行动中的问题的小提琴:http://jsfiddle.net/9WX5b/1/

2 个答案:

答案 0 :(得分:23)

请求元素的offsetHeight可以很好地完成所有操作。您可以使用此函数强制重排并向其传递已更改样式的元素:

function reflow(elt){
    console.log(elt.offsetHeight);
}

并在需要回流的地方调用它。请参阅此示例:http://jsfiddle.net/9WX5b/2/

编辑:最近需要这样做,并想知道是否有一个比console.log更好的方法。您不能只编写elt.offsetHeight作为它自己的语句,因为优化器(至少Chrome)不会触发重排,因为它只是访问没有设置getter的属性,甚至不需要评估它。因此,AFAIK最便宜的方式是void(elt.offsetHeight),因为它不确定void是否有副作用。 (可能被覆盖或某事,idk)。

答案 1 :(得分:3)

function reflow( element ) {
    if ( element === undefined ) {
        element = document.documentElement;
    }
    void( element.offsetHeight );
}

它适用于Chrome和FF,并且似乎是最简单,最便携的ATM方式。