如果我这样运行:
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 开始动画到这些位置。
看起来初始翻译不能在与转换设置相同的调用堆栈中动态设置?或者,更清楚地说,如果在同一个调用堆栈中设置了转换和转换,则转换将始终优先。
这是为什么?
最佳答案
由于与每次重排相关的计算成本,大多数浏览器通过排队更改并分批执行更改来优化重排过程。在这种情况下,您将覆盖浏览器识别的元素的内联样式信息。浏览器对第一个更改进行排队,然后对第二个更改进行排队,然后最终决定是否应该进行回流,它是一次性完成的。 (将更改分成两个函数调用并不重要。)尝试更新任何其他样式属性时,同样会发生这种情况。
您始终可以使用以下任一方法强制浏览器重排:
- offsetTop, offsetLeft, offsetWidth, offsetHeight
- scrollTop, scrollLeft, scrollWidth, scrollHeight
- clientTop、clientLeft、clientWidth、clientHeight
- getComputedStyle()(IE 中的当前样式)
所以只需将您的第一个函数更改为:
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 从样式表中动态创建和删除样式规则。在这里阅读更多:programmatically changing webkit-transformation values in animation rules
关于javascript - 无法在同一调用堆栈中的转换之前动态设置初始元素转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9303080/