大部分浏览器对元素几何改变时候的重排做了优化。据说是这样子,一定时间内本应多次重排的改变,浏览器会hold住,仅一次重排。其中如果使用分离的一步处理过程,例如计时器,依然多次重排。例如,当我们应用transition动画的时候,希望从0px
变化到100px
. 你如果如下代码:
dom.style.left = "0px"; dom.style.left = "100px";
元素是不会从0~100像素动画的,因为现代浏览器有自己的优化机制,它只会处理后面的
dom.style.left = "100px",
可以通过访问元素的OffsetHeight属性,来让起重绘,$.fn.redraw = function(){ $(this).each(function(){ var redraw = this.offsetHeight; });};
知道为啥这样访问offsetHeight可以实现功能吗??原因很简单,访问元素的offsetHeight属性会导致该元素的回流,重新计算元素的位置。但是这样实现动画可能会造成性能问题。
之前转载的一篇翻译文章提到了 “影响回流的因素”:
- 调整窗口大小(Resizing the window)
- 改变字体(Changing the font)
- 增加或者移除样式表(Adding or removing a stylesheet)
- 内容变化,比如用户在input框中输入文字(Content changes, such as a user typing text in
an input box) - 激活 CSS 伪类,比如 :hover (IE 中为兄弟结点伪类的激活)(Activation of CSS pseudo classes such as :hover (in IE the activation of the pseudo class of a sibling))
- 操作 class 属性(Manipulating the class attribute)
- 脚本操作 DOM(A script manipulating the DOM)
- 计算 offsetWidth 和 offsetHeight 属性(Calculating offsetWidth and offsetHeight) 根据此可以实现一个jquery插件,让元素回流并重绘。ex. el.style.left=20px; a = el.offsetHeight;el.style.left=22px;
- 设置 style 属性的值 (Setting a property of the style attribute)
还可以通过setTimeout来实现。
h.style.marginTop = '50px'
setTimeout(function(){
h.style.marginTop = '150px'
},130)
具体的过渡实现,可参考maccaw的博客:http://blog.alexmaccaw.com/css-transitions