龙空技术网

动态更改动画keyframes修改样式

沐土之夏 171

前言:

目前看官们对“js 添加样式”大致比较重视,小伙伴们都需要学习一些“js 添加样式”的相关文章。那么小编在网摘上搜集了一些有关“js 添加样式””的相关知识,希望大家能喜欢,各位老铁们一起来了解一下吧!

背景

最近做了一个上线滚动文字的走马灯组件,通过关键帧@keyframes at-rule 来定义滚动;

由于我的滚动条目是动态的,个数不定,所以需要动态计算时间段显示的内容。

思路

就是@keyframe 设置在不同时间显示不同的元素,通过绝对定位来实现,动态控制元素的位置来控制显示哪个元素。

div {  animation: myfirst 5s;  animation-iteration-count: infinite; // 无限循环}@keyframes myfirst {  0% {    left: 0;    top: 0;  }  ,  25% {    left: 0;    top: -24px;  }  50% {    left: 0;    top: -48px;  }  100% {    left: 0;    top: -72px;  }}// 兼容性的代码省略

上面是基本的代码,但是我的条目是动态的,所以时间刻度需要动态计算,但是@keyframe 没有像元素样式的动态的属性,不能计算后赋值给元素;在网上的查询后,最终使用动态给样式对象插入新的样式的方式来实现。

动态更改@keyframes

const styleSheet = document.styleSheets[0];styleSheet.insertRule("keyframe的定义", 3);

网上的大致思路就是上面的代码,但是有几个坑。

styleSheets 分内部和外部样式

我在写 demo 测试的时候,由于我没有内嵌样式,所以看到的都是外部,所以我就把样式插入到了第一个里面,但是放到项目里面发现,竟然报错提示没有rules属性。因为如果有内嵌样式,第一个是内嵌样式,内嵌的 rules 属性是没有值的。所以为了保险不要直接在第一个对象中插入。最好插入到最后一个

const styleSheet = document.styleSheets[document.styleSheets.length - 1];

通过属性设置animation-name属性

开始我是按照网上的写法,直接设置 animation 属性

animation: myfirst 5s;

由于我是 react,使用了 webpack 打包,打包后,名字myfirst被重新命名了。由于 demo 中的样式比较少,可以通过document.styleSheets看到,样式中 myfirst 被打包后的名字;并且也可以看到它的位置。

但是在项目中,样式比较多,根据打包后的名字去设置比较困难的

const styleSheet = document.styleSheets[document.styleSheets.length - 1];const keyframesName = styleSheet.rules[0].name;const keyframesStr = `${keyframesName} {0% {          left: 0px;          top: 0px;        }        ${keyframesItem.join("")}      }`.replace(/\s+/g, "");const keyframes = `@keyframes ${keyframesStr}`;const keyframes_webdit = `@-webkit-keyframes ${keyframesStr}`; /* Safari 和 Chrome */styleSheet.insertRule(keyframes, styleSheet.rules.length);styleSheet.insertRule(keyframes_webdit, styleSheet.rules.length);
动态设置 keyframes

这个需要用到insertRule()方法

styleSheet.insertRule(keyframes_webdit, styleSheet.rules.length);
最终解决方案在样式中不指定 animation-name,通过 js 操作样式属性设置,这样生成 keyframes 时,就不用去获取打包生成的名字。样式直接插入最后的 styleSheets 中在 js 中指定animationName
// 在全局定义名字const keyframesName = "text-carousel-keyframesName-key-asdf8324-df324s";// 关键代码const styleSheet = document.styleSheets[document.styleSheets.length - 1];const keyframesStr = `${keyframesName} {0% {          left: 0px;          top: 0px;        }        ${keyframesItem.join("")}      }`.replace(/\s+/g, "");const keyframes = `@keyframes ${keyframesStr}`;const keyframes_webdit = `@-webkit-keyframes ${keyframesStr}`; /* Safari 和 Chrome */styleSheet.insertRule(keyframes, styleSheet.rules.length);styleSheet.insertRule(keyframes_webdit, styleSheet.rules.length);// jsx <section          className={styles.itemContainer}          style={{            animationDuration: animationDuration,            animationName: keyframesName,   // 设置名字            ...contentStyle,          }}        >...

标签: #js 添加样式