不能在相同调用堆栈中转换之前动态设置初始元素转换 [英] Cannot dynamically set initial element translation before transition in same call stack

查看:99
本文介绍了不能在相同调用堆栈中转换之前动态设置初始元素转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我运行这样的:

  var div1 = document.getElementById('div1'),
div2 = document.getElementById('div2');

function setAnimation(){
div1.style.webkitTransform ='matrix(1,0,0,11200,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保留在它的位置



<$>如果我删除startAnimation并将setAnimation改为:



<$> p $ p> 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

  • scrollBoot,scrollLeft,scrollWidth,scrollHeight

  • clientTop,clientLeft,clientWidth,clientHeight

  • getComputedStyle()(IE中的currentStyle)



因此,只需将第一个函数更改为:

  var computedStyles = []; 

function setAnimation(){
div1.style.webkitTransform ='matrix(1,0,0,11200,0)';
div2.style.webkitTransform ='matrix(1,0,0,1,0,0)';

//强制div的1和2回流
computedStyles [div1] = div1.clientHeight;
computedStyles [div2] = div2.clientHeight;
}

现在浏览器将执行初始转换。



由于在尝试解决回流/重绘问题时会出现一些麻烦,例如:这,我总是建议使用CSS动画,即使你必须使用CSSOM动态创建和删除样式表中的样式规则。在此处阅读更多:以编程方式更改动画规则中的webkit转换值


If I run something like so:

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 animates offscreen just fine, yet div1 remains in it's place at 0,0 and a change is never seen.

If I remove startAnimation altogether and change setAnimation to:

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';
}

I would see both elements animate to those positions, both starting from 0,0.

It looks like an initial translation cannot be set dynamically within the same call stack as the setting of the transition? Or, more clearly, if a transition and transform are both set within the same call stack, transition will always take precedence.

Why is this?

解决方案

Because of the computation costs associated with each reflow, most browsers optimize the reflow process by queuing changes and performing them in batches. In this case, you are overwriting the inline style information of the elements, which the browser recognizes. The browser queues the first change and then the second before finally deciding that a reflow should occur, which it does all-at-once. (It doesn't matter that you have separated the changes into two function calls.) This would similarly happen when trying to update any other style property.

You can always force the browser to reflow by using any of the following:

  • offsetTop, offsetLeft, offsetWidth, offsetHeight
  • scrollTop, scrollLeft, scrollWidth, scrollHeight
  • clientTop, clientLeft, clientWidth, clientHeight
  • getComputedStyle() (currentStyle in IE)

So just change your first function to this:

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;
}

And now the browser will perform the initial transformations. You don't need two functions to accomplish this, just force the reflow in-between.

Due to some headaches that can occur when trying to solve reflow/repaint issues like this, I always suggest using CSS animations, even if you have to dynamically create and remove style rules from a stylesheet using the CSSOM. Read more here: programmatically changing webkit-transformation values in animation rules

这篇关于不能在相同调用堆栈中转换之前动态设置初始元素转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆