js 動(dòng)態(tài)添加、修改css3 @keyframes

一. 效果圖

效果圖

二. 需求

拖動(dòng)一個(gè)shape,小圓點(diǎn)ball運(yùn)動(dòng)位置也變化。

三. 技術(shù)分析

其中運(yùn)動(dòng)ball是反復(fù)重復(fù)一個(gè)動(dòng)作運(yùn)動(dòng),不能使用transition漸變方式寫,因?yàn)閠ransition只能執(zhí)行一次漸變效果,重復(fù)運(yùn)動(dòng)最佳的方式就是采用animation。

四. 問題

@keyframes寫在css中是寫死的,此時(shí)需要結(jié)束js操作@keyframes,那js是如何操作@keyframes呢,下面是我花了一天查詢資料加上自己的摸索,解決了兼容IE的解決方案。

五. js操作@keyframes解決方案

  1. 為了方便查詢以及后面循環(huán)過多產(chǎn)生的性能問題,一開始我們就通過js創(chuàng)建@keyframes
// js創(chuàng)建@keyframes,ball從定位在(10,10)的位置運(yùn)動(dòng)到(100,100) 的位置
const runkeyframes =` @keyframes ball-run{
    0%{
        left: 10px;
        top: 10px;
    }
    100%{
        left: 100px;
        top: 100px;
    }
}`
// 創(chuàng)建style標(biāo)簽
const style = document.createElement('style');
// 設(shè)置style屬性
style.type = 'text/css';
// 將 keyframes樣式寫入style內(nèi)
style.innerHTML = runkeyframes;
// 將style樣式存放到head標(biāo)簽
document.getElementByTagName('head')[0].appendChild(style);
<style>
  .ball{
      width:10px;
      height:10px;
      border-radius:50%;
      background-color:#fff
  }
</style>
<!-- 這是ball的標(biāo)簽和樣式 -->
<div id="ball" class="ball" style="animaition: ball-run 10s infinite;"></div>
  1. js修改@keyframes
// 獲取所有的style樣式
// 尋找ball keyframes對應(yīng)的style樣式
// 獲取方式:根據(jù)animation運(yùn)動(dòng)的名稱ball-run查詢到對應(yīng)的keyframes對應(yīng)的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方法用來從當(dāng)前樣式表對象中刪除指定的樣式規(guī)則
ballRunKeyframes.styleSheet.deleteRule(animation.index);
//重新定義ball從定位在(20,30)的位置運(yùn)動(dòng)到(400,500) 的位置
const runkeyframes =` @keyframes ball-run{
    0%{
        left: 20px;
        top: 30px;
    }
    100%{
        left: 400px;
        top: 500px;
    }
}`;
// insertRule方法用來給當(dāng)前樣式表插入新的樣式規(guī)則.
ballRunKeyframes.styleSheet.insertRule(keyFrames, animation.index);
// 此時(shí)已經(jīng)修改好了ball-run 對應(yīng)的keyframes了,但是在坑爹的IE中小球ball依然沒有改變?yōu)樗倪\(yùn)動(dòng)方式,解決方案就是,從新刷新ball Dom中的animation的值
const ball = document.getElementById('ball');
// 隨便給一個(gè)animation的名稱
ball.setAttribute('style','animaition: ball-run1 10s infinite;');
setTimeout(_=>{
  // 1ms后糾正animation的名稱
  ball.setAttribute('style','animaition: ball-run 10s infinite;');
},1)

六. 總結(jié)

  1. 上面僅提供解決思想,建議不要復(fù)制,因?yàn)檫@里的代碼是我在簡書上手寫,如有疑問咱們可以留言相互探討。
  2. 注意:
    1) keyframes單獨(dú)寫在一個(gè)style中,方便getkeyframes函數(shù)的內(nèi)部遍歷,想知道為什么,可以將document.styleSheets打印出來看看里面的結(jié)構(gòu)就明白了。
    2) js修改keyframes之后IE可能沒有效果,需要重新刷新animation值
  3. 參考insertRule方法用來給當(dāng)前樣式表插入新的樣式規(guī)則.,deleteRule方法用來從當(dāng)前樣式表對象中刪除指定的樣式規(guī)則兩個(gè)方法
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容