js 动态添加、修改css3 @keyframes

2019-02-26  本文已影响0人  zackxizi

一. 效果图

效果图

二. 需求

拖动一个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方法用来从当前样式表对象中删除指定的样式规则两个方法
上一篇 下一篇

猜你喜欢

热点阅读