不定高元素动画实现方案(下)

news/2025/9/23 13:09:06/文章来源:https://www.cnblogs.com/xwwin/p/19103101

前情

最近小程序接了一个需求,需要实现一个列表,列表可展开收起,展开收起需要有一个动画效果,而列表个数不定且每项内容高度也不固定,所以是一个不定高的收起展开效果,于是特意抽时间尝试了一些动画实现方案,特此记录

通过js+css变量来实现

实现思路是js获取要实现动画元素的高度,再通过css变量把高度设置在元素上,当hover的时候,把元素的高度设为css变量

关键代码如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>JS Bin</title>
</head>
<body><div class="container"><div class="inner"><div class="header">header</div><ul class="list" id="list" style="--height:0px"><li>scale111111111</li><li>scale2222222222</li><li>scale333333333</li><li>scale444444444</li></ul></div></div>
</body>
</html>
*{margin: 0;padding: 0;
}
.container{width: 100%;overflow: hidden;
}
.header{width: 100%;height: 48px;background-color: #ccc;display: flex;align-items: center;justify-content: center;
}
.list{background-color: green;height: var(--height)
}
document.addEventListener('DOMContentLoaded', () => {var list = document.querySelector('#list')list.style.setProperty('--height', list.scrollHeight + 'px')
})

演示地址:https://jsbin.com/besufuyihe/edit?html,css,js,output

20250920_200532

注意:

css动画使用比js要简单,同时性能上也会有优势,所以能用css实现的就尽量用css实现,此方式兼容性棒,JS干预也不是特别多

通过js+Flip动画来实现

FLIP是一种高性能动画技术,常用于实现复杂动画,代表四个步骤:

  1. First(初始):记录元素的初始状态
  2. Last(最终):设置元素到最终状态并记录
  3. Invert(反转):计算差异并将元素恢复到初始状态
  4. Play(播放):应用过渡效果并播放动画

代码如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>JS Bin</title>
</head>
<body><div class="container" id="container"><div class="inner"><div class="header">header</div><ul class="list"><li>Flip111111111</li><li>Flip2222222222</li><li>Flip333333333</li><li>Flip444444444</li></ul></div></div>
</body>
</html>
*{margin: 0;padding: 0;
}
.container{width: 100%;height: 48px;overflow: hidden;
}
.header{width: 100%;height: 48px;background-color: #ccc;display: flex;align-items: center;justify-content: center;
}
.list{background-color: green;
}
document.addEventListener('DOMContentLoaded', () => {// 获取容器元素const containero = document.querySelector('#container')// 鼠标进入容器时的FLIP动画实现containero.addEventListener('mouseenter', () => {// 第一步(F-First):记录初始状态(隐式的,初始高度为48px)// 第二步(L-Last):设置元素为最终状态,获取自然高度containero.style.height = 'auto';const conh = containero.scrollHeight; // 获取内容实际高度// 第三步(I-Invert):将元素恢复到初始状态containero.style.height = '48px';containero.offsetHeight; // 触发重绘,确保样式应用// 第四步(P-Play):添加过渡效果并播放动画到最终状态containero.style.transition = 'height .4s';containero.style.height = conh + 'px';})// 鼠标离开时恢复初始高度containero.addEventListener('mouseleave', () => {containero.style.height = '48px';})
})

演示地址:https://jsbin.com/barihazasi/edit?html,css,js,output

20250920_203017

注意:

Flip用于实现一些复杂动画是非常常见的方式,动画还是使用css3的transition,还是遵守一个原则,能用css实现动画的还是用css来做

纯js来实现

早期js实现动画都是使用setInterval/setTimeout来实现动画效果的,现在如果要用js来实现动画可以使用requestAnimationFrame来代替,来看一下他们的对比

1. 触发时机与刷新频率

  • setTimeout/setInterval
    • 按照指定的时间间隔(毫秒)触发回调函数
    • 时间间隔是近似值,实际执行会受 JavaScript 线程繁忙程度影响
    • 即使页面处于后台或隐藏状态,仍可能继续执行
    • 刷新频率固定,无法与显示器刷新率同步
  • requestAnimationFrame
    • 由浏览器决定执行时机,通常与显示器刷新率同步(60Hz 屏幕约每 16ms 执行一次)
    • 自动调整执行频率以匹配设备性能
    • 当页面处于后台或标签页隐藏时,会暂停执行以节省资源
    • 执行时机在浏览器重绘之前,确保动画平滑

2. 性能表现

  • setTimeout/setInterval
    • 可能导致动画卡顿或跳帧,因为无法与浏览器渲染周期对齐
    • 多个定时器同时运行时可能导致性能问题
    • 高频率定时器 (如 10ms) 可能导致浏览器过度渲染,消耗不必要的资源
  • requestAnimationFrame
    • 浏览器会优化动画执行,确保流畅性
    • 自动调整帧率,在性能不足时降低频率
    • 不会在页面不可见时执行,节省 CPU/GPU 资源

关键代码如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>JS Bin</title>
</head>
<body><div class="container" id="container"><div class="inner"><div class="header">header</div><ul class="list"><li>js111111111</li><li>js2222222222</li><li>js333333333</li><li>js444444444</li></ul></div></div>
</body>
</html>
*{margin: 0;padding: 0;
}
.container{width: 100%;height: 48px;overflow: hidden;
}
.header{width: 100%;height: 48px;background-color: #ccc;display: flex;align-items: center;justify-content: center;
}
.list{background-color: green;
}
document.addEventListener('DOMContentLoaded', () => {const containero = document.querySelector('#container')// 初始高度为48px(与CSS中定义的一致)const initH = 48;// 获取容器完全展开时的高度const conh = containero.scrollHeight;// 每一帧增加/减少的高度像素const step = 5;// 标记动画是否正在运行,防止多次触发let isAnimating = false;containero.addEventListener('mouseenter', () => {// 如果已经在动画中,则不重新开始if (isAnimating) return;// 获取当前高度作为起点let currentHeight = parseInt(containero.offsetHeight);isAnimating = true;const expand = function () {// 增加高度currentHeight += step;// 检查是否达到目标高度if (currentHeight >= conh) {containero.style.height = conh + 'px';isAnimating = false;return;}// 设置新高度并继续动画containero.style.height = currentHeight + 'px';requestAnimationFrame(expand);}// 开始展开动画requestAnimationFrame(expand);})// 鼠标离开时恢复初始高度containero.addEventListener('mouseleave', () => {// 如果已经在动画中,则不重新开始if (isAnimating) return;// 获取当前高度作为起点let currentHeight = parseInt(containero.offsetHeight);isAnimating = true;const collapse = function () {// 减少高度currentHeight -= step;// 检查是否达到初始高度if (currentHeight <= initH) {containero.style.height = initH + 'px';isAnimating = false;return;}// 设置新高度并继续动画containero.style.height = currentHeight + 'px';requestAnimationFrame(collapse);}// 开始收起动画requestAnimationFrame(collapse);})
})

演示地址:https://jsbin.com/kunuqomale/edit?html,css,js,output

20250920_210140

注意:

早期想实现动画都是依赖js来做的,看这代码量就知道用JS实现既复杂又性能一般,现在css3动画已经兼容性非常好了,推荐用css3动画来实现,使用js来实现动画是最终选择了,当然真正项目开发也不会自己去写js动画函数了,市面上有很多强大易用的动画库,早期jQuery就自带动画函数,还有我觉得市面上最强大的动画库GSAP是目前js实现动画的首选了

总结

对于做技术的我们,每天都是提出问题解决问题的一个过程,过程中会尝试各种方案,因为解决问题的方案千千万,每种方案都有自己的适合场景,此篇文章记录了实现不定高内容过渡效果的另外三种实现方式,上中下篇文章一共介绍了9种实现动画的方式

个人知识有限,如果你有更好的实现方案,希望不吝分享,一起学习一起进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/912636.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Zabbix7 监控USG6300E 并发IPv4会话数 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

商城网站开发 多少钱哪个网站可以接任务做兼职

文章目录 1 untiy和网页相互通信2 打开新页面&#xff08;同标签页和新标签页&#xff09;3 获取网页的URL4 解析Url内的参数5 后处理与色彩空间问题 1 untiy和网页相互通信 看这个文章 2 打开新页面&#xff08;同标签页和新标签页&#xff09; 先看本文untiy和网页相互通信…

网站推广专员面试少儿编程加盟店8

此项目模板是使用Create React App构建的&#xff0c;它提供了一种简单的方法来启动React项目而无需构建配置。 使用Create-React-App构建的项目包括对ES6语法的支持&#xff0c;以及几种非官方/尚未最终形式的Javascript语法 先看效果 这个例子可以帮助你深入理解在 Redux 中 …

网站开发实训教程jsp网站开发介绍

需要使用到 Pretty Json插件。 一、安装方法 sublime 下&#xff0c;按快捷键 Comand control p&#xff0c; 输入install Package,然后回车 等几秒钟&#xff0c;加载启动进程完毕后弹出的页面中输入pretty json, 然后回车 等待几秒钟&#xff0c;可以查看Sublime 最下面的…

做自我介绍的网站的图片素材龙岩淘宝设计

Description Input 第一行为两个整数n, m。第二行有n个整数&#xff0c;为a1&#xff0c;a2, …, an。 Output 包含n行&#xff0c;每行m个1~nm的正整数&#xff0c;各不相同&#xff0c;以空格分开。如果有多解&#xff0c;输出任意一组解&#xff1b;如果无解&#xff0c;输出…

深圳知名网站设计公司排名郑州市城乡建设局官网

RBD Exploded View&#xff08;与Exploded View SOP类似&#xff09;从中心炸开几何体&#xff0c;以更好查看被破碎和约束的碎块&#xff1b; 可视化高精度和低精度几何体的不同&#xff0c;Show Proxy Geometry显示代理几何体&#xff1b; Show Constraints显示约束&#xff…

淮安软件园有做网站的吗软件定制开发的发展前景

文章速览 1、添加节点核心代码示例 2、展开节点核心代码示例注意 坚持记录实属不易&#xff0c;希望友善多金的码友能够随手点一个赞。 共同创建氛围更加良好的开发者社区&#xff01; 谢谢~ 1、添加节点 核心代码 TreeView.Nodes.Add()示例 foreach (var item in content){…

丘受网站谁做的网球吧东莞网站推广优化网上推广公司

绝对路径使用&#xff1a; 在项目中build文件夹下的webpack.base.conf.js的 使用如下&#xff1a; import mock from /mock/mock.js; html 相对路径使用 1. 当需要引用 同一目录下的文件&#xff0c;直接输入文档, 如下 <img src”bg.jpg” /> 2、当需要引用下一级目录…

做网站接电话一般要会什么镇江建筑公司排名最新

目录 一 用户账号与组账号 ①Linux中每个用户账号是通过 UID来唯一标识的 账户类型UID号描述特点超级管理员0权限受到限制的用户程序用户 1-499 &#xff08;CentOS 6以前&#xff09; 1-999 &#xff08;CentOS 7以后&#xff09; 不登录的用户&#xff0c;系统默认的情况拥…

网站建设的目标客户网站建设主流语言

pytdx 分笔 数据 https://rainx.gitbooks.io/pytdx/content/pytdx_hq.html 「 通达信 」的基本使用及常用设置 https://zhuanlan.zhihu.com/p/558652417 通达信功能介绍&#xff1a;还没用过“超级盘口”&#xff1f;你损失大了&#xff01; https://baijiahao.baidu.com/s?i…

F010 Vue+Flask豆瓣图书推荐大素材可视化平台系统源码

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

记一次debian13 进入紧急模式

记一次debian13 进入紧急模式进入紧急模式后 输入root密码登陆root 然后运行 systemctl --failed出现 run-user-1000-doc.mount loaded failed failed 查看了/etc/fstab 发现多了几项莫名奇妙的东西 大致是挂载错误了 …

可视化网站制作企业网站功能需求文档

以往“看房跑断腿”的时代在vr全景看房出现后就得到了很大的解决&#xff0c;如今疫情和“宅经济”的双重影响下&#xff0c;各行各业不得不寻求线上转型&#xff1b;而vr全景对于房地产等行业便是一个很好的转型方式。vr全景看房也被一些朋友称之为是3D看房和VR看房&#xff0…

作品集怎么做网站荆轲网络做网站

考研竞赛智慧e数学的广告&#xff1a;鸡汤所谓“理解”&#xff0c;所谓“智商”&#xff0c;本质上最终都归到"记忆",还有一点就是能够发现自己“记忆”中各个零散的知识点的关系。所谓“智商”高低的人&#xff0c;其实是强化这些“记忆”的能力的不同&#xff0c;…

湘潭网站建设 磐石网络最好网站怎么接入百度地图

为什么80%的码农都做不了架构师&#xff1f;>>> 链接&#xff1a;http://zhaoyuqiang.blog.51cto.com/6328846/1214718 转载于:https://my.oschina.net/L110/blog/402042

静安网站建设公司熊岳网站怎么做

文章目录 异常与中断的关系中断的处理流程异常向量表Linux 系统对中断的处理ARM 处理器程序运行的过程程序被中断时&#xff0c;怎么保存现场Linux 系统对中断处理的演进Linux 对中断的扩展&#xff1a;硬件中断、软件中断硬件中断软件中断 中断处理原则&#xff1a;耗时中断的…

网站搜索排名优化软件珠海市官网网站建设品牌

一、什么是npm? npm&#xff0c;全称为Node Package Manager&#xff0c;是Node.js的包管理器。它允许开发者分享和重用代码&#xff0c;提供了一个巨大的开源库供开发者选择和使用。通过npm&#xff0c;你可以轻松安装、更新和管理Node.js的库和工具。 二、npm的主要功能 …

莱芜网站建设价格东圃手机网站建设电话

题解&#xff1a; 很经典的网络流 对于每个厨师拆点分开统计 1倍 2倍 3倍 n&#xff08;mp)^2 有点大 动态加边 即对于每个厨师有了i才会有i1 不过好像还是有点卡常&#xff1f;&#xff1f; 代码&#xff1a; #include <bits/stdc.h> using namespace std; #define INF …

漂亮全屏网站盐城网站开发市场

文章目录 一、简单运算二、广播运算1.广播的基本规则2.广播操作的例子 三、运算函数 参考&#xff1a;与凤行 张量的数学运算是深度学习和科学计算中的基础。张量可以被视为一个多维数组&#xff0c;其在数学和物理学中有广泛的应用。这些运算包括但不限于加法、减法、乘法、除…

古镇网站建设公司安徽酒店网站建设

有时&#xff0c;我们会遇到UI稿有文字描边的效果&#xff0c;比如下图的效果。 一、给需要描边的文字加一个id选择器 例如&#xff1a; 二、css写法&#xff1a; number,{//这个是实现文字描边的关键&#xff0c;也就是‘空心文字’&#xff0c;这个是定义文字字符的描边的宽…