动态生成CSS轮播动画

本文介绍了如何使用CSS实现动态轮播动画,包括固定展位个数的静态动画和任意展位个数的动态动画。详细讲解了关键帧的运用、超出隐藏及展位循环等技巧,同时解决了动态生成keyframes时遇到的插入规则异常问题。

阅读盛书强博客原文

需求

  1. 实现轮播动效,每个展位显示3s,然后0.5s滚动到下一个展位,依次循环播放。
  2. 展位个数是服务端下发的任意数量。

思路

  1. 实现固定展位个数的静态轮播CSS动画。
  2. 实现任意展位个数的动态轮播CSS动画。

动作

固定展位个数轮播静态CSS动画

众所周知,帧动画可以控制不同帧的样式,简单在菜鸟Demo可以看到,详见如下keyframes动画示例

上面帧是一直在滚动,并不是需求中要求的停下展示一会再滚动。灵机一动,两帧直接不产生位移不就可以做到停下展示了么?详见如下keyframes&停下再滚动动画示例

上面帧是一个大长条在滚动,和轮播不是一回事。这也难不倒我,如果把视窗固定,让大长条从视窗前滚动,可不就是轮播效果么。直接固定父布局作为视窗,超出隐藏,即 overflow: hidden。详见如下keyframes&停下再滚动&超出不显示动画示例

现在还剩下最后一个问题,最后一个左滑时后面是空白,而需求是轮播,即最后一个后面接着第一个,不断循环。这个问题就考到了轮播的关键了(划重点),有种最简单做法就是展位循环生成100个,最后一次会滚动出空白,不过一般用户不会看到,所以很难发现,勉强能混过去。详见如下keyframes&停下再滚动&超出不显示动画&多组件循环示例

显然,这种勉强混日子的方案入不了眼,其实这个问题本身很简单,自己在纸上画一下就出来了。

1. 尾部肯定要加上第一个展位,否则最后一个左滑尾部是空白。
2. 这一步也是最关键的一步,其实啥也不用干,因为此刻回复到最初状态,最后一个和第一个都是第一个展位内容,因为内容一样,不会产生视觉跳变,虽然实际上的确变换了。

稍微用下面一张分解图就理解了。

具体详见如下keyframes&停下再滚动&超出不显示动画&加一组件循环示例

任意展位个数的动态轮播CSS动画

上面的样式是写死在html文档里,不满足需求中要求的服务端下发任意个数,这个思路比较简单,根据服务的下发的展位个数使用代码生成CSS样式就可以了,这么个通用问题肯定有现成方案,Google搜索一下关键字“动态生成keyframes”,比较下找到了一篇动态更改keyframes

第一步肯定是如何使用代码生成目标CSS样式内容,这个参考静态CSS照葫芦画瓢修改一下参数即可,详见下图代码示意。

第二步将生成的CSS动画样式注入到全局上下文,确保设置了属性能生效。动态更改keyframes在我的项目里面实测有问题,简单说就是通过styleSheet.insertRule插入样式,成功的前提是目标styleSheet本身已有样式,即styleSheet.rules数组非空,上述文章也说到该问题,作者通过在document.styleSheets尾部styleSheet插入的rules来规避,但是这种在尾部styleSheet.rules为空下依旧报“Uncaught DOMException: Failed to execute ‘insertRule’ on ‘CSSStyleSheet’: Cannot access StyleSheet to insertRule”异常。

这个异常从字面上看是没有权限,咋一看是兼容性问题,我在本地Chrome浏览器调试没有遇到,发布就出问题了。Google上有很多人遇到,几个方案试了还是崩溃。其中insertRule()规则无法注入文章虽然没有解决问题,但是带来了欢乐,作者抛出问题后又一个回复是将动态生成写成静态…,作者的回复给我整乐了,“回答很棒,下次不要答了”,👍。

继续搜索下发现了Uncaught DOMException: Failed to execute ‘insertRule’ on ‘CSSStyleSheet’,是通过生成style标签插入DOM的做法,一时半会不太理解,感觉像是另外一种方案来绕过上面问题。

此时和同事永健深入交流了一下,直接在异常处断点,发现document.styleSheets的最后一个styleSheet是非内联CSS(通过css url拉取加载),对应rules为空,此时我才发现,为啥不直接报rules数组为空,非整个不明觉厉的“Cannot access StyleSheet to insertRule”,让我在“没有权限”的兼容性错误方向迅猛的奔跑。进一步看主文档html的DOM树,也的确一一对应,我们项目内联CSS是第一个,手动改成第一个测试通过。

接着永健让我通过创建style标签的方式将生成的CSS样式注入DOM树,这也可以有效避免styleSheet.insertRule改动其他上下文CSS,更加安全可靠,自然也不会有上面的异常。这个是个简单DOM加style标签动作,代码如下图:

最后附上完整动态生成CSS轮播动画示例

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值