最新要闻
- 世界看点:原来是他们!退市股获举牌4个交易日翻倍,步步高系大佬要进董事会
- 天天即时看!注意!天孚通信:股东朱国栋计划减持公司股份不超过约395万股
- 游戏主播被大额打赏后剃光头!结果被坑惨:打赏退款了
- 尽享丝滑!MWC现场体验领克08魅族Flyme Auto车机:流畅度爆表 环球新要闻
- 焦点资讯:萧敬腾求婚好多地方下雨 “雨神”真有这么神?
- 15万的特斯拉廉价新车Model 2跳票了:延期到2025年
- 今日快讯:能否追上高铁?凯迪拉克CT5-V推出全新改装套件 动力可达1000匹
- 每日看点!未来可期!农村三胞胎姐妹高分同超一本线
- 北交所日报:指数调整回补缺口 曙光鼎智双双大涨
- 特斯拉Model Y的劲敌来了 溜背造型+电动尾翼 全新蔚来EC6实车曝光 报道
- 滚动:中国互联网协会重申:我国人工智能已进入全球第一梯队
- Intel Arc显卡驱动打鸡血:游戏性能飙升最高3.13倍!
- 全球热点评!骁龙8 Gen2没到极限!24GB运存手机不是终点 你觉得有必要吗?
- 高温再度来袭!北方气温将高于南方四大火炉城市|环球即时看
- ST深天: 关于落实《关于中国证监会深圳监管局行政监管措施决定书的书面整改报告》相关整改措施的公告-全球报道
- 天天速递!知嘛家整屋案例 | 116㎡现代简约风,超强收纳颜值功能拉满!
手机
光庭信息跌4.57% 2021上市超募11亿2022扣非降74% 时快讯
搜狐汽车全球快讯 | 大众汽车最新专利曝光:仪表支持拆卸 可用手机、平板替代-环球关注
- 光庭信息跌4.57% 2021上市超募11亿2022扣非降74% 时快讯
- 搜狐汽车全球快讯 | 大众汽车最新专利曝光:仪表支持拆卸 可用手机、平板替代-环球关注
- 视点!美国首位女总统即将诞生?拜登恐怕要提前下岗,美政坛迎来变局?
- 当前速递!用理想仪器实现更好的颗粒 德国新帕泰克亮相CPHI & PMEC China获好评
- 微粒贷怎么申请开通 开通方法如下
- 焦点简讯:心疼!这位40岁的云南缉毒警,已是满头白发
家电
记录--不定高度展开收起动画 css/js 实现
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
不定高度展开收起动画
最近在做需求的时候,遇见了元素高度展开收起的动画需求,一开始是想到了使用 transition: all .3s;
来做动画效果,在固定高度的情况下,transition
动画很好使,满足了需求,但是如果要考虑之后可能还会有更改的情况下,如果每次都是用固定高度来做动画,会显得很繁琐,也很呆,就想到了使用 height: auto;
来做高度动画,但是,众所周知,高度设置成 auto
时是不会触发 transition
动画的
.container { height: 0; background-color: #ccc; overflow: hidden; transition: all .3s;}.container:hover { height: 1000px;}
效果如图,不能满足动画的要求
(资料图片仅供参考)
在一番查找实验之后,目前发现了如下几种方法:
1.max-height
最大高度
transition
动画可以响应max-height
.container { max-height: 0; background-color: #ccc; overflow: hidden; transition: all .3s;}.container:hover { max-height: 1000px;}
但是使用 max-height
做动画有一个问题,如果设置的最大高度越大,但是实际高度确与最大高度相差甚远,那么整体的动画速度就会非常快,动画的时间只会是 实际高度 / 最大高度 * 动画时间,因为展开动画原本预期高度是设置的最大高度,所以整体时间是以最大高度完全展开所用时间来进行的,但是当到达实际高度的时候动画就停止了,所以最终动画时间会与期望时间相差甚远。
max-height
方法做动画也是一个好方法,如果能够确定大致高度的话,使用此方法是最简单也是最快的方法,但是如果不能确定大致高度或整体高度经常变化的话,可以考虑其他方法。
2. grid
动画
grid
网格布局,是一种较新的布局,号称是最强大的布局方案。grid
布局不是本文的介绍重点,并且较为复杂,如果感兴趣的话,可以参考相关文章,如:
- 写给自己看的display: grid布局教程
- 最强大的 CSS 布局 —— Grid 布局
grid
布局中可以使用 fr
单位,fr
单位是支持过度动画的(0fr=>1fr
),将 grid
布局下的子元素,初始设置为0fr
,在 :hover
状态下设置为 1fr
,就能够实现不定高度动画效果,但是如果子元素有内容,在设置 0fr
的时候,会被其内容撑开,所以要给子元素添加 min-height: 0;
.container { display: grid; grid-template-rows: 0fr; overflow: hidden; transition: all .3s;}.container:hover { grid-template-rows: 1fr;}.container .child { min-height: 0;}
如果想要实现带有基础高度的展开收起动画,我们可以设置min-height: 100px;
.container .child { min-height: 100px;}
虽然此时实现了带有基础高度的动画效果,但是可以看到,如果我把 transition: all 3s;
的动画时间设置的较大,就可以看出来,虽然有基础高度,但是整个动画的效果还是要实现 0fr
到 1fr
的动画效果,基础高度部分不会有动画效果,这也算是一个小的缺点,如果动画时间较短并且基础高度也不大的话,可以这样使用,并不会有太大的影响效果。
但是 grid
布局有可能有兼容性的问题,grid-template-rows
动画的支持可能有兼容性问题
3. js 控制动画
写这篇文章的原因是因为在看项目代码的时候看见了 $(.xx).slideDown()
方法实现了元素的下滑动画,觉得很不错,想学习一下怎么实现的,实现效果如下:
但是在看元素的时候却只能看见下面的样子,发现不是 css 实现的,是使用 js 不断改变元素的高度来实现的:
我又去看了一下 ant-design
的 Menu
组件,通过观察元素,发现其也是不断改变高度来实现的(Ps: 我并没有去看源码,如果有误,多谢指正)。
实现
首先要思考整个实现的思路
展开的时候,元素从无到有,我们应该首先获取整个元素的实际高度使用 offsetHeight
来获取,获取到整体高度后就要计算每一次增加或者减少的高度,通过定时器不断增加或减少元素的高度,直到到了最大高度或 0 后停止
展开
const element = document.getElementById("container");let expandTimer = null;let offsetHeight = 0;// 获取元素总高度element.style.display = "block";let height = 0;// 先将 display 设置为 block,获取到的 offsetHeight 才是正确的高度,之后才能设置元素高度offsetHeight = element.offsetHeight;const stepHeight = offsetHeight / 30;element.style.height = height + "px";expandTimer = setInterval(() => { height += stepHeight; if (height >= offsetHeight) { clearInterval(expandTimer); element.style = null; return; } element.style.height = height + "px";}, 10);
收起
let collapseTimer = null;offsetHeight = element.offsetHeight;let height = offsetHeight;const stepHeight = offsetHeight / 30;element.style.height = height + "px";collapseTimer = setInterval(() => { height -= stepHeight; if (height <= 0) { clearInterval(collapseTimer); element.style = null; return; } element.style.height = height + "px";}, 10);
现在能够正确展开收起,但是我们在展开收起的时候也会有相反的操作,比如鼠标进入元素展开离开收起,在展开的过程中鼠标离开了,我们应该立刻就将元素收起,而不是等动画结束后在进行下一个动画,所以要将展开收起操作合并操作才可以
const element = document.getElementById("container");let expandTimer = null;let collapseTimer = null;// 我认为在一次展开后,直到收起完成之前,这个元素的实际高度都不应该发生变化,但是可以在下一次展开时发生变化,所以在展开时会进行赋值,在收起完成时会将此值清空let offsetHeight = 0;let stepHeight = 0;const handleClick = () => { // 如果当前 expandTimer 值存在,就标识当前是正在展开或已经展开,接下来要进行的是收起操作 if (expandTimer) { clearInterval(expandTimer); expandTimer = null; // 收起时的初始高度是元素的当前实际高度,即使是元素在展开动画过程中,也要从当前元素高度进行收起动画 let height = element.offsetHeight; collapseTimer = setInterval(() => { height -= stepHeight; if (height <= 0) { // 高度小于等于 0 代表动画完成,将数据进行重置 clearInterval(collapseTimer); offsetHeight = 0; // 要将元素的高度置为 null,不然会影响下一次展开时获取正确的高度 element.style.height = null; // display 设为 null,要将元素隐藏 element.style.display = "none"; return; } element.style.height = height + "px"; }, 10); } else { clearInterval(collapseTimer); collapseTimer = null; // 获取元素总高度 element.style.display = "block"; let height = 0; 如果当前没有 offsetHeight 就要重新获取 if (!offsetHeight) { offsetHeight = element.offsetHeight; // 每一次给元素添加或减少的高度,除以 30 是自己设定的,跟下面定时器的每次间隔时间一起控制整个高度动画的时长,也可以给函数添加第二个时间参数,可以自由控制动画时间 stepHeight = offsetHeight / 30; } else { // 如果有 offsetHeight 就代表正在进行收起动画,应该从收起动画的当前高度进行展开动画 height = element.offsetHeight; } element.style.height = height + "px"; expandTimer = setInterval(() => { height += stepHeight; if (height >= offsetHeight) { // 当前高度如果已经到了元素的实际高度,就要清除定时器 clearInterval(expandTimer); // 将 expandTimer 设为 1 是因为当前是以 expandTimer 判断是否正在或已经进行了展开动画,所以要在完成是设为 1,在收起动画的开始时会将值设为 null expandTimer = 1; element.style = null; return; } element.style.height = height + "px"; }, 10); }};
最终实现效果
4. 总结
上面的三种方式实现效果都是各有千秋 - max-height
方法实现是最简单,也是效率最高的方式,但是也有动画时间不定的缺陷 - grid
方式实现比 max-height
稍微复杂一些,但是整体效果要比 max-height
更好,但是目前浏览器的支持方面可能有所不足,如果有低版本的兼容性要求的话,还是不能使用 - js
方式整体最复杂,但是却没有上面两种方式的缺陷与问题,使用范围也更广泛,但是是 js
的实现方式,性能肯定是不如 css
,虽然不如,但是由于整体操作也较为简单,所以也不会有什么性能问题
几种方法的取舍全看个人需求了。
如果有鼠标进入展开,离开收起的操作,可以配合使用 onmouseover
onmouseout
事件来监听鼠标的进入离开。
其他还有像是 transform: scale(0);
的实现也是可以,但是整体动画效果就是一个缩小的效果,而且元素还会有占位问题,如果没什么要求也是可以使用的。
本文转载于:
https://juejin.cn/post/7249536369474486329
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
关键词:
记录--不定高度展开收起动画 css/js 实现
今日播报!Cognos教程_编程入门自学教程_菜鸟教程-免费教程分享
LRU 缓存淘汰算法
Mac反编译安卓APK
世界看点:原来是他们!退市股获举牌4个交易日翻倍,步步高系大佬要进董事会
【金融街发布】财政部:5月地方债发行规模为7554亿元 新增债券占比近四成_即时看
天天即时看!注意!天孚通信:股东朱国栋计划减持公司股份不超过约395万股
游戏主播被大额打赏后剃光头!结果被坑惨:打赏退款了
尽享丝滑!MWC现场体验领克08魅族Flyme Auto车机:流畅度爆表 环球新要闻
焦点资讯:萧敬腾求婚好多地方下雨 “雨神”真有这么神?
15万的特斯拉廉价新车Model 2跳票了:延期到2025年
今日快讯:能否追上高铁?凯迪拉克CT5-V推出全新改装套件 动力可达1000匹
js的Map数据类型
Sudo堆溢出漏洞(CVE-2021-3156)复现
Spring 赌上未来一击,推出响应式框架 WebFlux,代码更优雅,性能更强! 最新
解锁高质量文档转换:通过Java应用程序免费将PDF转换为XPS
每日看点!未来可期!农村三胞胎姐妹高分同超一本线
北交所日报:指数调整回补缺口 曙光鼎智双双大涨
特斯拉Model Y的劲敌来了 溜背造型+电动尾翼 全新蔚来EC6实车曝光 报道
滚动:中国互联网协会重申:我国人工智能已进入全球第一梯队
Intel Arc显卡驱动打鸡血:游戏性能飙升最高3.13倍!
全球热点评!骁龙8 Gen2没到极限!24GB运存手机不是终点 你觉得有必要吗?
高温再度来袭!北方气温将高于南方四大火炉城市|环球即时看
ST深天: 关于落实《关于中国证监会深圳监管局行政监管措施决定书的书面整改报告》相关整改措施的公告-全球报道
php如何解决高并发|每日热门
今日讯!业务安全情报第十七期 | 国际航班上,小“票代”在疯狂倒卖高价票
在 Java、Python、JavaScript 和 Go 中拥抱异步
数据交换不失控:华为云EDS,让你的数据你做主 环球微头条
天天速递!知嘛家整屋案例 | 116㎡现代简约风,超强收纳颜值功能拉满!
【新华500】新华500指数(989001)28日探底回升微跌0.11%
当前观点:索尼推送满血包:ZV-E1相机支持4K/120p和1080P/240p
车主看后想骂人 特斯拉一充电站全被“割了”:只剩桩不见枪
天天热消息:河北邢台雷雨夜震撼闪电撕破夜空:闪电如怒吼银蛇
警惕!侧躺着玩手机可能会影响你的颜值 同时威胁健康
【世界聚看点】80%毕业生都出国了 是马斯克公司最大“生源地”?清华大学发声
腾讯在深圳宝安启用三个与AI大模型相关的平台
解决TrueNAS中Smb共享文件路径不区分大小写的问题 每日精选
GIS地形场景的应用与前景:从美景欣赏到环境保护与城市规划|焦点热门
讯息:遥望科技启动商家大会,瑜大公子现身会场分享进阶故事
焦点热文:助力首都建设 浦发银行北京分行发售北京市地方政府柜台债券
今天解禁!RTX 4060终于来了 2399元买吗?
芯片之母 是德EDA升级支持6G设计:速度快10倍|当前热门
王宝强做客东方甄选!被俞敏洪问是否还相信爱情
24GB内存时代来了!一加真我全都上24GB超大内存:性能激进 当前播报
CDPR:《赛博朋克2077》首发没那么糟糕 都怪跟风黑 全球今日讯
天天速看:全国电力行业学习宣传贯彻习近平新时代中国特色社会主义思想和党的二十大精神宣讲比赛举办
热点在线丨MongoDB(二)
奥特银河格斗:被官方遗忘的形态与奥特曼阿古茹成为了全剧最惨
当前热文:男子在动车上霸座充电被行拘 网友惊叹处罚严厉:7天还少?
华为孟晚舟:5.5G是必然之路、下行可达万兆!
世界热议:上海发布高温黄色预警,预计本市大部地区最高温将超过35度
过烂路前避震可能会断 丰田召回近60万辆汽车|当前速看
核污水强行入海无视反对!日本官方全面检查排海设备:污染倒计时
环球通讯!致6死20余伤!广州宝马撞人案司机二审结果出炉:被判死刑
天天最资讯丨大学生游戏本怎么选?RTX4060加持 华硕天选4锐龙版到手7999元
【世界独家】世界最丑狗狗比赛胜者决出:七岁中国冠毛犬夺冠
焦点快看:众智科技:6月27日融资买入551.57万元,融资融券余额4327.64万元
[python] 基于matplotlib-scalebar库绘制比例尺
易基因|表观遗传学与脑卒中:DNA甲基化的作用及衰老对血脑屏障修复的影响
RabbitMQ的死信队列,延时队列
复旦微电间接股东章勇被批评 正拟发不超20亿可转债|环球观点
Uzi请假原因找到了!担任亚运会《英雄联盟》国家队教练:指导下路
5G专利全球第一 华为向日本公司收专利费:日企有三大麻烦了
通讯!笔记本电脑坐上过山车 下半年或复苏
全球通讯!任天堂打造!《超级马力欧兄弟大电影》7月14日上线网播:B站、腾讯已预告
多女子开直播看望杭州跳河救人外卖小哥 本人回应:别利用我带货
安徽省利辛县发布大风蓝色预警 环球关注
直播系统源码知识分享:解你忧愁!降低直播延迟的实现 全球热议
焦点信息:2023成都迎大运蓉港公益足球赛直播时间+入口
中通快递宣布标快服务升级!全国66城送货上门 不上必赔
首发骁龙8 Gen2领先版+24GB内存!红魔8S Pro真机首度公布:今年唯一真全面屏|环球关注
特斯拉一统充电江湖!沃尔沃宣布接入超充网络-热讯
非常明亮的火球在德国上空爆炸:闪耀夜空 随后解体_环球热点评
家长千万不要随意私拆学生档案:违规还违法 影响求职入学
全球观焦点:伦理片日本 在线(关于伦理片日本 在线的基本详情介绍)
鹿驻(关于鹿驻的基本详情介绍)_播报
台版苹果手机怎么样(台版苹果手机)
山东东营一男子驾车将妻子反复碾压致死,已被刑拘
甘肃张掖:人工增雨作业助力祁连山生态修复
世界快看点丨苹果内部体验Vision Pro:重量太大
光庭信息跌4.57% 2021上市超募11亿2022扣非降74% 时快讯
七彩化学再收警示函 因业绩预告不准、信披不及时 环球速看
山东省纪委监委网站通报
石药集团CPO301获加拿大临床试验批准
全球通讯!最新!500亿芯片巨头遭遇"空袭"!周鸿祎官宣:考上清华大学研究生
【环球时快讯】天津南1000千伏变电站主变压器扩建工程已取得核准和水土保持批复
钢城区这个片区房屋征收补偿方案发布!
国网新疆岳普湖县供电开展乡村振兴领域腐败问题专项整治工作
有人假冒国家机关名义伪造文件!农业农村部郑重声明|天天观焦点
圣洁防水3奖、1讲、1展、1演闪耀长春丙纶大会
天天动态:汉字找茬王高考显眼包怎么过
【世界聚看点】墙裂推荐!4类免费自媒体工具,你一定用的上!
浙能集团与大连造船签署绿色航运战略合作备忘录
终于理解为什么都说陈妍希“不上镜”,她本人原来长这样
全球最大水光互补电站——柯拉光伏电站投产发电_天天快报
新密2村书记获评郑州市“十佳”
广州考古发现珠三角面积最大的商时期文化遗存|快消息
【全球报资讯】清华“轮椅博士”毕业了,他选择……
世界快播:猪哥电影全集(猪哥电影)
搞机研究所 | 语音好用观感差强人意 岚图梦想家车机体验_环球热点评