这篇文章发布于 2015年01月22日,星期四,15:45,归类于 JS实例。 阅读 80778 次, 今日 9 次 35 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=4546
一、小美,你好
此“小美”非东四街的小美,而是“小而美研究”的简称,实用小技巧,分分钟Get, 积累足够多,量变到质变。
本文应该就属于这个范畴,提炼的成果就是十来行代码。
现在web技术不断发展,视图与数据渲染更多由前端呈现,后台更多与数据打交道。于是,我们会经常看到这样的交互场景。页面加载,看到一个框框里面有个菊花在转,然后内容呈现;或者点击个按钮,菊花在转,然后列表动态加载呈现。例如:
是不是没有任何问题?确实,功能上OK,有菊花,用户也愿意等。但是,大家有没有觉得所有交互,出现菊花→出现内容,都是“砰砰砰”很生硬的感觉,尤其当内容是动态,高度不确定的时候。我们使用一些比较好的手机APP(如微信)的时候一定不会有这样的感觉,整个交互流程都是很流畅的,就像山涧的泉水,涓涓细流到山脚,而不是巨人在峡谷走路的感觉。
所以,如果菊花的呈现到内容的展示能够通过自然的动画过渡呈现,势必会增强用户体验。
而动态内容呈现主要变化的关键因素就是——高度,而过渡效果最佳利器是CSS3 transition, 于是,脑中不禁疑问,是不是可以借助CSS3 transition实现动态内容的高度动画呈现,渐进增强用户体验。
其实,早在12年的时候,我就开始了这方面的尝试,若有兴趣可以查看此文:“更多|收起交互中渐进使用transition动画”。我自己也瞅了瞅,发现当年的我讲废话的本领甩了现在的我两条长安街。大家直接从Part5 看就好了。 其中,受限于当年略显稚嫩的技术,里面获得容器高度的方法,有些傻,大家就假装没看到。
二、CSS3 transition的难点
如果直接一行CSS代码就可以让动态呈现动画化,那就不需要本文了,早就各个站点都是这类优质体验的交互了。究其根本就是CSS3 transition的一个局限性,对"auto"
*冷淡!嘛意思?
大家很好理解,所谓“过渡”,就是从一个地方到另外一个地方,比方说,从0
到100
. 但是,你来个从0
到auto
, 傻眼了吧。大学时看过一部美国科幻片《心灵传输者》,其中男主也不是想瞬间位移就瞬间位移的,也是需要知道目的地和路径的。
然而,当我们在一个div
呈现动态内容的时候,由于我们并不知道里面的内容(都说了是动态的嘛),所以,我们的height
其实都是auto
,于是,就算transition: height .35s
走起,也不会有动画效果的,我们需要的是固定值。
于是难点和关键点来了,如何赋予固定高度值?
三、固定高度值与transition触发
说白了很简单,当前高度固定值,获得动态内容载入后的高度固定值,再style
设置,over~
代码细节我就不讲了,其实没什么人关心的,“我需要的是代码,代码!”估计很多人心里是这么咆哮的。
// 高度无缝动画方法 var funTransitionHeight = function(element, time) { // time, 数值,可缺省 if (typeof window.getComputedStyle == "undefined") return; var height = window.getComputedStyle(element).height; element.style.transition = "none"; // 本行2015-05-20新增,mac Safari下,貌似auto也会触发transition, 故要none下~ element.style.height = "auto"; var targetHeight = window.getComputedStyle(element).height; element.style.height = height;element.offsetWidth = element.offsetWidth;element.offsetWidth; if (time) element.style.transition = "height "+ time +"ms"; element.style.height = targetHeight; };
十行出头点代码。
element
就是容器元素;如果transition
你是写在CSS中的,time
参数可以不要,例如:
element { transition: height 250ms; overflow: hidden; } funTransitionHeight(element)
funTransitionHeight
名字如果你不喜欢,可以自己改掉。IE9+有效,IE10+有动画,IE6~IE8老样子,所谓渐进增强。
百闻不如一见,您可以狠狠地点击这里:不定高度动态元素height CSS3 transition过渡demo
点击页面上“点击我”按钮,里面就有有高度不固定内容呈现,大伙儿就可以看到内容呈现时候不是砰砰砰了,而是歘歘歘~
如何调用?很简单,初始化时候funTransitionHeight()
一下,赋个固定值;然后每次菊花完毕,内容载入后在funTransitionHeight()
一下,动画就来啦。也就是说,相比你们以前的JS代码,就多了一行funTransitionHeight(element)
调用而已,是不是实用又低成本!
四、结束语
貌似最近折腾了很多与菊花有关的文章,菊花恒久远,一颗永流传!
感谢阅读,欢迎交流菊花心得!
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=4546
(本篇完)
- 伪类+js实现CSS3 media queries跨界准确判断 (0.390)
- Canvas中颜色过渡动画效果的实现 (0.370)
- 小tip: CSS3 animation渐进实现点点点等待提示效果 (0.367)
- 获取元素CSS值之getComputedStyle方法熟悉 (0.314)
- CSS :visited伪类选择器隐秘往事回忆录 (0.314)
- 如何在HTML和JS中设置和获取var CSS变量 (0.314)
- 开源移动端元素拖拽惯性弹动以及下拉加载两个JS (0.265)
- “更多|收起”交互中渐进使用transition动画 (0.264)
- 翻译 - CSS高峰会议内容精选 (0.232)
- CSS3 Transitions, Transforms和Animation使用简介与应用展示 (0.232)
- jQuery之使用slideToggle实现垂直下拉菜单 (RANDOM - 0.055)
在var targetHeight = window.getComputedStyle(element).height;前设置断点的话,好像会有一个瞬态的高度跳跃,可不可以在母div中嵌入一个子div,检查子div的高度呢,毕竟万一页面复杂的话跳来跳去会影响性能。
可以,我就是这么做的,父div大小不变,子div设为auto,然后父子同时改变,避免跳动
var oldHeight = element.offsetHeight
element.style.height = “auto”
var autoHeight = element.offsetHeight
element.style.height = oldHeight + “px”
setTimeout(function(){
element.style.height = autoHeight + “px”
},0)
这样不是更简单吗
element.offsetWidth = element.offsetWidth;
这句有什么意义呢
也不是太懂为什么要初始化一下
触发浏览器重排.
通过getComputedStyle获取元素数值高度,才能用于transition触发动画,模糊值不能触发动画。
我居然看见了 e宠 的广告。。
如果是一个隐藏的div,但是这个div的高度不定,怎样实现这个效果呢?研究了好久,没想到更好的办法呢
您好。我想问下element.style.height = “auto”;在这段代码里起到什么作用呢?下面不是又element.style.height = height;了吗?
我试过把element.style.height = “auto”删掉,该元素高度就不会随子元素变化;如果我把它放在element.style.height = height;后面,整个transition的变化很生硬。
本人初学前端,请大家多多指教(*^__^*)
element.style.height = “auto”; // 将高度设置为 auto,这样下面 targetHeight 的值就是将要调整的高度
element.style.height = height; // 设个设置回原来高度,这样就可以利用 transition 从当前高度过渡到 targetHeight 这个高度
你结婚了没
还要通过JS,不知道有没有只用CSS就可以实现的方法?
http://codepen.io/Dudy/pen/pvRRzB
刚看到这个,使用max-width来实现transition,纯JS实现
看下
用世界之窗浏览器试了下demo,发现效果只在第一次有效,后面就没有效果了。
我要访问
请教如何解决使用了transform后导致浏览器滚动条变化和闪动的问题
@miao 可参考此文:“纯CSS让overflow:auto页面滚动条出现时不跳动”。
别老菊花菊花的 妹子看到会有想法 你考虑过这个问题的严重性吗?
找到一个bug,在360安全浏览器极速模式下貌似无效,楼主可以测试下
确实是这样的,只有第一次加载的时候才会自适应高度的!其他的不行
请教一个问题:
setTimeout(function() {
if (time) element.style.transition = “height “+ time +”ms”;
element.style.height = targetHeight;
}, 15);
即使我把15改成1,动画效果依然正常,但是如果我把setTimeout去掉,就直接没有动画效果了,这是为什么
@calmcarry 触发动画效果需要触发重绘,setTimeout就有这个作用。
看了一下关于javascript线程的解释,大致明白是怎么回事了,多谢
看了一下,这里的 setTimeout 和触发重绘没有关系。
这里的延时只是为了让 loading 显示一会儿。
如果没有延时,box.innerHTML 直接被赋值两次,loading 被紧跟着的第二次内容取代了,就看不到 loading(菊花) 了。
LZ够幽默,不错!挺喜欢你的作品!
容器定义一个min-height
min-height??? 没看懂这个例子吧你
第一次调运的目的是给box设置一个初始高度吧,给个初始固定高度,可以不执行哇
var height = window.getComputedStyle(element).height;
element.style.height = “auto”;
var targetHeight = window.getComputedStyle(element).height;
element.style.height = height;
element高度设成”auto”时为什么不会闪一下?
因为css渲染器还没反应过来吗?
@Kenny 浏览器有性能优化机制,短时间内的多个属性值变化只会一次渲染。
我一直以为在设置style的时候,渲染和js是同步执行的。
现在明白了,原来计算和渲染是分离的。
抱歉,我不是很明白为什么要先初始化一次?我没搞懂
给box一个初始高度,点击按钮的时候插入的加载框高度是100%
用的话还可以,但是出来第一次就调用一下,是不是对性能不太好!!!
段子手,泥濠