强制浏览器在更改 CSS 时触发回流

IT技术 javascript html css reflow
2021-02-13 02:37:59

我正在构建基于 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 的 left 属性以触发 CSS3 动画。(假设:从 -1200px 到 0px)。

问题是什么?浏览器简化了更改并且不制作任何动画。

斯托扬斯特凡在他的博客中写了一篇关于回流的问题在这里,但在这种情况下,试图迫使元件上的回流不起作用。

这是执行此操作的一段代码(为了简化,我跳过了浏览器前缀):

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个回答

请求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)。

你甚至不需要console.log. 刚刚elt.offsetHeight
2021-03-19 02:37:59
仅使用 offsetHeight 可能会被智能优化器编译出来。Console.log 可能会阻止它,但也很嘈杂,也可以删除。相反,您可以使用纪念品变量。这是一个轻微的内存泄漏,但如果你很聪明,你只会有一个。使用可写变量,您可以将其分配给自身。
2021-04-03 02:37:59
在这里您可以找到一长串强制回流的属性和方法:gist.github.com/paulirish/5d52fb081b3570c81e3a 我认为不涉及 console.log() 的解决方案更好,因为它不会污染控制台。@vaxquis 解决方案更好。
2021-04-05 02:37:59
谢谢你,你救了我的一天!此外,我使用了 translate3d(如果支持)来获得更流畅的动画,并且在任何浏览器中一切都像魅力一样。再次感谢一位。
2021-04-10 02:37:59
function reflow( element ) {
    if ( element === undefined ) {
        element = document.documentElement;
    }
    void( element.offsetHeight );
}

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