Javascript 无法在同一调用堆栈中动态设置转换前的初始元素转换
如果我这样做:Javascript 无法在同一调用堆栈中动态设置转换前的初始元素转换,javascript,css,Javascript,Css,如果我这样做: var div1 = document.getElementById('div1'), div2 = document.getElementById('div2'); function setAnimation() { div1.style.webkitTransform = 'matrix(1,0,0,1,1200,0)'; div2.style.webkitTransform = 'matrix(1,0,0,1,0,0)'; div1.sty
var div1 = document.getElementById('div1'),
div2 = document.getElementById('div2');
function setAnimation() {
div1.style.webkitTransform = 'matrix(1,0,0,1,1200,0)';
div2.style.webkitTransform = 'matrix(1,0,0,1,0,0)';
div1.style.webkitTransition = div2.style.webkitTransition = '-webkit-transform 2s ease';
}
function startAnimation() {
div1.style.webkitTransform = 'matrix(1,0,0,1,0,0)';
div2.style.webkitTransform = 'matrix(1,0,0,1,-1200,0)';
}
setAnimation();
startAnimation();
div2在屏幕外的动画效果很好,但是div1仍然保持在0,0的位置,并且从未看到任何变化
如果我完全删除startAnimation并将setAnimation更改为:
function setAnimation() {
div1.style.webkitTransform = 'matrix(1,0,0,1,500,0)';
div2.style.webkitTransform = 'matrix(1,0,0,1,-500,0)';
div1.style.webkitTransition = div2.style.webkitTransition = '-webkit-transform 2s ease';
}
我会看到两个元素都从0,0开始设置动画到这些位置
看起来无法在与转换设置相同的调用堆栈中动态设置初始转换?或者,更清楚地说,如果转换和转换都设置在同一调用堆栈中,则转换将始终优先
这是为什么?由于与每次回流相关的计算成本,大多数浏览器通过排队更改并成批执行更改来优化回流过程。在这种情况下,您将覆盖浏览器识别的图元的内联样式信息。浏览器将第一次更改和第二次更改排队,然后再最终决定是否应发生回流,这一过程一次完成。(将更改分为两个函数调用并不重要。)当尝试更新任何其他样式属性时,也会出现类似情况 您始终可以使用以下任意一种方法强制浏览器回流:
- 斜视,斜视,斜视,斜视
- scrollTop、scrollLeft、scrollWidth、scrollHeight
- clientTop、clientLeft、clientWidth、clientHeight
- getComputedStyle()(IE中的currentStyle)
var computedStyles = [];
function setAnimation() {
div1.style.webkitTransform = 'matrix(1,0,0,1,1200,0)';
div2.style.webkitTransform = 'matrix(1,0,0,1,0,0)';
// force div's 1 and 2 to reflow
computedStyles[div1] = div1.clientHeight;
computedStyles[div2] = div2.clientHeight;
}
现在浏览器将执行初始转换。您不需要两个函数来完成这一点,只需在两者之间强制回流即可
由于在尝试解决像这样的回流/重绘问题时可能会出现一些令人头痛的问题,我始终建议使用CSS动画,即使您必须使用CSSOM从样式表中动态创建和删除样式规则。阅读这里的更多内容:我认为一种解决方案是在很短的setTimeout内调用第二个函数,尽管您的问题更多的是为什么会发生这种情况,而不是如何解决。我也想知道解决这个问题的最佳实践方案。是的,这就是我目前解决这个问题的方法。感觉很脏。哇,非常感谢。这是一直困扰我的事情之一。不过,我还有一个问题:为什么将过渡设置为settimeout(即使延迟最小)会迫使浏览器回流?我不确定,因为我不是一个浏览器开发人员,但我最好的猜测是,浏览器试图在何时回流上保持智能。如果它有回流更改排队,然后将出现一个timout,则需要这段时间来回流页面(因为它无论如何都会等待)。我认为超时本身就是触发器,这就是为什么它可以延迟1毫秒甚至0毫秒并不重要。setTimeout在这方面已经取得了很多成功,我只是不确定它是否像我列出的其他方法一样普遍适用于跨浏览器。