顾名思义,是否有适当的方法来设置一些初始CSS属性(或类),并告诉浏览器将其转换为另一个值?
var el = document.querySelector('div'), st = el.style; st.opacity = 0; st.transition = 'opacity 2s'; st.opacity = 1;
这不会激活Chrome 29 / Firefox 23中元素的不透明度。这是因为(源):
[…]您会发现,如果同时应用两组属性,则立即应用一组属性,然后浏览器将尝试优化属性更改,而忽略您的初始属性并防止过渡。在幕后,浏览器在绘画之前先批处理属性更改,这通常会加快渲染速度,但有时可能会产生不利影响。 解决方案是在应用两组属性之间强制重绘。一个简单的方法就是通过访问DOM元素的offsetHeight属性[…]
[…]您会发现,如果同时应用两组属性,则立即应用一组属性,然后浏览器将尝试优化属性更改,而忽略您的初始属性并防止过渡。在幕后,浏览器在绘画之前先批处理属性更改,这通常会加快渲染速度,但有时可能会产生不利影响。
解决方案是在应用两组属性之间强制重绘。一个简单的方法就是通过访问DOM元素的offsetHeight属性[…]
offsetHeight
实际上,该破解确实适用于当前的Chrome / Firefox版本。更新了代码(小提琴 - Run打开小提琴后单击以再次运行动画):
Run
var el = document.querySelector('div'), st = el.style; st.opacity = 0; el.offsetHeight; //force a redraw st.transition = 'opacity 2s'; st.opacity = 1;
但是,这有点黑,据报道在某些android设备上不起作用。
建议使用,setTimeout以便浏览器有时间执行重绘,但是它也失败了,因为我们不知道重绘将花费多长时间。猜测适当的毫秒数(30-100?)以确保发生重绘就意味着牺牲性能,而不必要地闲置是希望浏览器在那短时间内表现出某种魔力。
setTimeout
通过测试,我发现了另一个解决方案,使用requestAnimationFrame在最新的Chrome上运行良好:
requestAnimationFrame
var el = document.querySelector('div'), st = el.style; st.opacity = 0; requestAnimationFrame(function() { st.transition = 'opacity 2s'; st.opacity = 1; });
我假设requestAnimationFrame等到下一次重画开始之前,然后执行回调,因此浏览器不会批处理属性更改。此处不确定,但可以在Chrome 29上正常使用。
更新: 经过进一步测试,该requestAnimationFrame方法在Firefox 23上效果不佳- 多数情况下似乎失败。
是否有合适的或推荐的(跨浏览器)方式来实现这一目标?
目前还没有一种干净的方法(不使用CSS动画-有关使用CSS动画的示例。有一个规范错误14617,很遗憾,自2011年提交以来就没有得到纠正。
setTimeout在Firefox中无法可靠地运行这是设计使然。
我不确定requestAnimationFrame-对原始问题的编辑说它也不可靠,但是我没有调查。(更新:看起来requestAnimationFrame至少一位Firefox核心开发人员认为是可以进行更多更改的地方,而不必一定看到先前更改的效果。)
window.getComputedStyle(elem).opacity;
请注意,仅运行getComputedStyle(elem)是不够的,因为它是惰性计算的。我相信您从getComputedStyle询问哪个属性都没有关系,重新样式仍然会发生。请注意,询问与几何相关的属性可能会导致更昂贵的回流。
getComputedStyle(elem)