扫码关注官方订阅号
style-animate 显示
正常display:none的元素变为display:block,是不产生任何动画过渡的,但是为什么访问元素的offsetHeight属性后却可以产生动画?原理是什么?
offsetHeight
学习是最好的投资!
谢邀并强答:浏览器的DOM操作或许不是一个API一个API接连执行的,而是会将一系列相似的API列队以后一次执行,已达到一定效率并减少开销,单次DOM操作的开销特别大。而调用item.offsetHeight属性打断了元素的样式修改,原本是display和left一起提交的,被打断后display先提交了,然后才提交的left;我测试过,把 item.offsetHeight; 换成 window.getComputedStyle(item, null)["display"]; 也会产生动画。大概是不能在同时多个提交样式的语句中间插入样式读取的语句吧。当然,以上都是猜想,真实原理我并不知道。已关注话题,等待优解。
item.offsetHeight;
window.getComputedStyle(item, null)["display"];
刚刚有测试了如下代码:
item.style.display="block"; item.style.top="20px"; item.offsetHeight; //为什么在这里增加这个调用,就可以显示动画? //window.getComputedStyle(item, null)["display"]; //item.style.top="20px"; item.style.left="100px";
当 item.style.top="20px"; 分别置于 item.offsetHeight; 前后时动画效果是不一样的。置于前是,只有向右动画,置于后才有斜向右上的动画。正好说明了, item.offsetHeight; 确实对样式修改的DOM操作进行了分段。原本只需要进行一次DOM操作分成了两次。先渲染了display和top,然后才渲染left,所以可以看到left的动画。
item.style.top="20px";
offsetHeight会触发浏览器遍历dom,就这么简单,之前的提交已经生效(block),然后又遍历一遍dom,相当于更新了dom缓存,再增加效果。如果要使用动画,尽量不要连续触发offsetHeight/width,会造成页面reflow。
个人觉得跟css渲染有关,item没有block之前是不被渲染的,那么这是的left值无效的,在你block之后呢,样式才会渲染。那么此时left:20px就被left:100px覆盖了,transition是执行过渡的,此时就只有前值100px,没有后值,那么没有动画效果;item.offsetHeight; 这句代码估计使的left:20px得已渲染,然后item.style.left="100px";才会有改变值的效果。动画实现。(以上都是猜想,不合理请指正)
opacity:0到opacity:1的过渡
css里的transition设成了all,所有属性变化都会触发这个动画
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
谢邀并强答:
浏览器的DOM操作或许不是一个API一个API接连执行的,而是会将一系列相似的API列队以后一次执行,已达到一定效率并减少开销,单次DOM操作的开销特别大。
而调用item.offsetHeight属性打断了元素的样式修改,原本是display和left一起提交的,被打断后display先提交了,然后才提交的left;
我测试过,把
item.offsetHeight;换成window.getComputedStyle(item, null)["display"];也会产生动画。大概是不能在同时多个提交样式的语句中间插入样式读取的语句吧。当然,以上都是猜想,真实原理我并不知道。已关注话题,等待优解。
刚刚有测试了如下代码:
当
item.style.top="20px";分别置于item.offsetHeight;前后时动画效果是不一样的。置于前是,只有向右动画,置于后才有斜向右上的动画。正好说明了,item.offsetHeight;确实对样式修改的DOM操作进行了分段。原本只需要进行一次DOM操作分成了两次。先渲染了display和top,然后才渲染left,所以可以看到left的动画。offsetHeight会触发浏览器遍历dom,就这么简单,之前的提交已经生效(block),然后又遍历一遍dom,相当于更新了dom缓存,再增加效果。如果要使用动画,尽量不要连续触发offsetHeight/width,会造成页面reflow。
个人觉得跟css渲染有关,item没有block之前是不被渲染的,那么这是的left值无效的,在你block之后呢,样式才会渲染。那么此时left:20px就被left:100px覆盖了,transition是执行过渡的,此时就只有前值100px,没有后值,那么没有动画效果;
item.offsetHeight; 这句代码估计使的left:20px得已渲染,然后item.style.left="100px";才会有改变值的效果。动画实现。
(以上都是猜想,不合理请指正)
opacity:0到opacity:1的过渡
css里的transition设成了all,所有属性变化都会触发这个动画