js 动态添加、修改css3 @keyframes

博客围绕拖动shape时小圆点ball运动位置变化的需求展开。分析得出采用animation实现ball重复运动,因@keyframes写在css中是固定的,需用js操作。介绍了通过js创建和修改@keyframes的解决方案,还给出注意事项,如keyframes单独写在style中、修改后IE需刷新animation值。

一. 效果图

效果图

二. 需求

拖动一个shape,小圆点ball运动位置也变化。

三. 技术分析

其中运动ball是反复重复一个动作运动,不能使用transition渐变方式写,因为transition只能执行一次渐变效果,重复运动最佳的方式就是采用animation。

四. 问题

@keyframes写在css中是写死的,此时需要结束js操作@keyframes,那js是如何操作@keyframes呢,下面是我花了一天查询资料加上自己的摸索,解决了兼容IE的解决方案。

五. js操作@keyframes解决方案

  1. 为了方便查询以及后面循环过多产生的性能问题,一开始我们就通过js创建@keyframes

 

// js创建@keyframes,ball从定位在(10,10)的位置运动到(100,100) 的位置
const runkeyframes =` @keyframes ball-run{
    0%{
        left: 10px;
        top: 10px;
    }
    100%{
        left: 100px;
        top: 100px;
    }
}`
// 创建style标签
const style = document.createElement('style');
// 设置style属性
style.type = 'text/css';
// 将 keyframes样式写入style内
style.innerHTML = runkeyframes;
// 将style样式存放到head标签
document.getElementByTagName('head')[0].appendChild(style);

 

<style>
  .ball{
      width:10px;
      height:10px;
      border-radius:50%;
      background-color:#fff
  }
</style>
<!-- 这是ball的标签和样式 -->
<div id="ball" class="ball" style="animaition: ball-run 10s infinite;"></div>
  1. js修改@keyframes

 

// 获取所有的style样式
// 寻找ball keyframes对应的style样式
// 获取方式:根据animation运动的名称ball-run查询到对应的keyframes对应的style
  getkeyframes=(name)=> {
    var animation = {};
    // 获取所有的style
    var ss = document.styleSheets;
    for (var i = 0; i < ss.length; ++i) {
      const item = ss[i];
      if (item.cssRules[0] && item.cssRules[0].name && item.cssRules[0].name === name) {
        animation.cssRule = item.cssRules[0];
        animation.styleSheet = ss[i];
        animation.index = 0;
      }
    }
    return animation;
  }

const ballRunKeyframes = getkeyframes('ball-run');
// deleteRule方法用来从当前样式表对象中删除指定的样式规则
ballRunKeyframes.styleSheet.deleteRule(animation.index);
//重新定义ball从定位在(20,30)的位置运动到(400,500) 的位置
const runkeyframes =` @keyframes ball-run{
    0%{
        left: 20px;
        top: 30px;
    }
    100%{
        left: 400px;
        top: 500px;
    }
}`;
// insertRule方法用来给当前样式表插入新的样式规则.
ballRunKeyframes.styleSheet.insertRule(keyFrames, animation.index);
// 此时已经修改好了ball-run 对应的keyframes了,但是在坑爹的IE中小球ball依然没有改变为他的运动方式,解决方案就是,从新刷新ball Dom中的animation的值
const ball = document.getElementById('ball');
// 随便给一个animation的名称
ball.setAttribute('style','animaition: ball-run1 10s infinite;');
setTimeout(_=>{
  // 1ms后纠正animation的名称
  ball.setAttribute('style','animaition: ball-run 10s infinite;');
},1)

六. 总结

  1. 上面仅提供解决思想,建议不要复制,因为这里的代码是我在简书上手写,如有疑问咱们可以留言相互探讨。
  2. 注意:
    1) keyframes单独写在一个style中,方便getkeyframes函数的内部遍历,想知道为什么,可以将document.styleSheets打印出来看看里面的结构就明白了。
    2) js修改keyframes之后IE可能没有效果,需要重新刷新animation值
  3. 参考insertRule方法用来给当前样式表插入新的样式规则.deleteRule方法用来从当前样式表对象中删除指定的样式规则两个方法



作者:zackxizi
链接:https://www.jianshu.com/p/b7b347c9783e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

### CSS `@keyframes` 用法与示例 CSS 的 `@keyframes` 是一种用于定义动画关键帧的规则,允许开发者通过设置多个关键帧来控制动画在不同阶段的样式变化,从而实现流畅的动画效果。`@keyframes` 通常与 `animation` 属性结合使用,以将定义好的动画应用到具体的 HTML 元素上 [^3]。 #### 基本语法 `@keyframes` 的基本结构如下: ```css @keyframes animation-name { 0% { /* 初始状态样式 */ } 50% { /* 中间状态样式 */ } 100% { /* 最终状态样式 */ } } ``` 其中 `animation-name` 是动画的名称,`0%` 表示动画开始时的状态,`100%` 表示动画结束时的状态,而 `50%` 表示动画进行到一半时的状态。也可以省略 `0%` 和 `100%`,浏览器会自动推断出这些关键帧 [^3]。 #### 使用动画 定义完动画后,需要通过 `animation` 属性将其应用到元素上。例如: ```css .animated-element { animation: animation-name 2s ease-in-out infinite; } ``` 其中,`animation-name` 是之前定义的动画名称,`2s` 表示动画持续时间为 2 秒,`ease-in-out` 是缓动函数,控制动画的速度变化,`infinite` 表示动画无限循环 [^3]。 #### 示例:颜色变化动画 以下是一个简单的颜色变化动画示例: ```css @keyframes colorChange { 0% { background-color: red; } 50% { background-color: blue; } 100% { background-color: green; } } .color-box { width: 100px; height: 100px; animation: colorChange 3s linear infinite; } ``` 在这个例子中,`.color-box` 元素会在 3 秒内循环播放颜色变化动画,背景色从红色变为蓝色,再变为绿色 [^3]。 #### 在 `@keyframes` 中使用 CSS 变量 CSS 变量(也称为自定义属性)可以在 `@keyframes` 中使用,但需要注意浏览器兼容性。首先在全局或特定元素中定义变量,例如: ```css :root { --main-color: red; } ``` 然后在 `@keyframes` 中使用该变量: ```css @keyframes colorChangeWithVar { 0% { background-color: var(--main-color); } 100% { background-color: blue; } } ``` 虽然这种方法在现代浏览器中通常可行,但部分旧浏览器可能不支持在 `@keyframes` 中使用 CSS 变量。在这种情况下,可以考虑使用 JavaScript 动态修改变量值,或使用预处理器(如 SASS/LESS)生成多个动画版本 [^1]。 #### 动画属性详解 `animation` 属性是一个简属性,包含多个子属性: - `animation-name`:指定动画名称。 - `animation-duration`:指定动画完成一次所需的时间(如 `2s`)。 - `animation-timing-function`:指定动画的速度曲线(如 `linear`、`ease-in-out`)。 - `animation-delay`:指定动画开始前的延迟时间。 - `animation-iteration-count`:指定动画循环次数(如 `infinite` 表示无限循环)。 - `animation-direction`:指定动画是否反向播放(如 `normal`、`reverse`、`alternate`)。 - `animation-fill-mode`:指定动画执行前后应用的样式(如 `forwards`、`backwards`) [^3]。 #### 动画兼容性处理 为了确保 `@keyframes` 动画在不同浏览器中正常运行,可以使用浏览器前缀,例如 `-webkit-`、`-moz-`、`-o-` 等。现代浏览器通常已经支持无前缀版本,但在某些旧版本中仍需添加前缀: ```css @-webkit-keyframes colorChange { 0% { background-color: red; } 100% { background-color: blue; } } @keyframes colorChange { 0% { background-color: red; } 100% { background-color: blue; } } ``` 同时,建议使用工具如 [Autoprefixer](https://autoprefixer.github.io/) 自动添加所需的浏览器前缀 [^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值