Translate

2020年6月26日 星期五

即時操作 css

  

雖然可以用新的 css 取代舊的,這裡還是研究一下即時操作現有 css 的方式

document.styleSheets 可以取得目前網頁中所有的 css 資料, 回傳的陣列就是一個 <style></style> 的區域

  document.styleSheets[n].cssRules 

就是該區域中的每一個設定的陣列,

  document.styleSheets[n].cssRules[m].cssText 

就是這個 css 完整字串, 只是這個字串是唯讀的, 必須用

  document.styleSheets[n].deleteRule(m) 

來刪除這整個設定 (什麼爛設計) , 以及用

  document.styleSheets[n].insertRule("css字串",索引) 

來新增, 索引預設是 0 ,也就是新增後會在最前面,如果沒有把本來的刪掉,新增的效果不會顯示, 然後索引也不能比本來的 Rules 多很多,只能剛好接在後面

然後比較特別的是動畫的 keyframes 如果下面這個是 keyframes

document.styleSheets[n].cssRules[k]

那麼

document.styleSheets[n].cssRules[k].name 
//這個 keyframes 的名稱
document.styleSheets[n].cssRules[k].cssRules[kn] 
//這個 keyframes 裡頭的每個 n% 的設定
document.styleSheets[n].cssRules[k].cssRules[kn].keyText 
//就是 % 的名稱
document.styleSheets[n].cssRules[k].cssRules[kn].cssText
//完整的 css 內容

可以用

document.styleSheets[n].cssRules[k].findRule("100%")
//搜尋
document.styleSheets[n].cssRules[k].deleteRule("100%")
//刪除
document.styleSheets[n].cssRules[k].appendRule("100%{left:100px}")
//新增

在 firefox 和 chrome 即時改變 css 的值,會立刻反應,但是在 safari/iphone/ipad 只要遇到動畫,都會延遲以及不正常反應

寫到最後,覺得還是用新的 css 蓋掉舊的 css 比較好


<style>
.a06261
{
  position:relative;
}
.a06261 .id1
{
  position:absolute;
  width:1em;
  height:1em;
  background-color:#f00;
  left:0px;
  top:0px;
  animation:none 3000ms 0ms 1 linear;
}
@keyframes a06261_a1
{
  0%
  {
    left:0px;
  }
  100%
  {
    left:90%;
  }
}
</style>

<div class="a06261">
<div class="id1">
</div>  

<br><br><br><br>
<button id="a06261_b1" style="font-size:1em">Blue</button>
<button id="a06261_b2" style="font-size:1em">Red</button>
<button id="a06261_b3" style="font-size:1em">Add Key</button>
<button id="a06261_b4" style="font-size:1em">Del Key</button>
<div class="cssinfo">
</div>

</div>

<script>

(function()
{

  function findallcss(a)
  {
    let i;
    let h1="";
    let h2="";
    let hh="";
    let nn="";
    let r=[];

    for (i in document.styleSheets)
    {
      h1="";
      h2="";
      if (typeof(document.styleSheets[i])!="object") continue;

      try //必須設 try catch, 以避免 access cross-origin stylesheet 的錯誤
      {

        let cssr=document.styleSheets[i].cssRules;
        let j;
        h1+="<hr>"+i+":"+typeof(document.styleSheets[i])+"<hr>";


        for (j in cssr)
        {
            if (typeof(cssr[j])!="object") continue;

            if (cssr[j].toString()=="[object CSSKeyframesRule]")
            {
              nn=cssr[j].name+" ";
            }
            else
            {
              nn=cssr[j].selectorText+" ";
            }

            if (a && nn.indexOf(a)<0) continue;

            h2+=j+"_"+cssr[j].toString()+"_";
            h2+=nn;
            h2+="<br>";

            r.push(
            {
              css:document.styleSheets[i],
              index:j
            });

        }
        if (h2) hh+=h1+h2;
      }
      catch(e)
      {
        console.log(e);
      }
    }
    $(".a06261 .cssinfo").html(hh);
    return r;
  }
  function css2json(r)
  {
    let csstxt=r.css.cssRules[r.index].cssText;
    let cssname=csstxt.match(/(.*)\{/)[1];
    let a=csstxt.match(/\{(.*)\}/)[1].split(";");

    let i;
    let j={}

    for (i in a)
    {
      let k=a[i].split(":");
      if (k.length<2) continue;
      j[k[0].trim()]=k[1].trim();
    }

    j["cssname"]=cssname.trim();

    return j;
  }
  function json2css(j)
  {
    let i;
    let cssname=j.cssname;
    let hh="";
    for (i in j)
    {
      if (i=="cssname") continue;
      if (j[i]===null) continue;
      hh+=i+":"+j[i]+";";
    }
    return cssname+" {"+hh+"}";
  }
  function getkeyframes(r)
  {
    let i;
    let kr=r.css.cssRules[r.index];
    let rf=[];
    for (i in kr.cssRules)
    {
      if (typeof(kr.cssRules[i])!="object") continue;
      let f={css:kr,index:i,key:kr.cssRules[i].keyText};
      rf.push(f);
    }
    return rf;
  }
  function cssdelrule(r)
  {
    r.css.deleteRule(r.index);
  }
  function cssaddrule(r,cssstr)
  {
    r.css.insertRule(cssstr,r.index);
  }
  function cssdelkey(kf,key)
  {
    if (!key) key=kf.key;
    kf.css.deleteRule(key);
  }
  function cssaddkey(kf,keystr)
  {
    kf.css.appendRule(keystr);
  }
  $("#a06261_b1").on("click",function()
  {
    let r=findallcss(".a06261 .id1");
    let j=css2json(r[0]);
    j["background-color"]="#00f";
    let css=json2css(j);
    cssdelrule(r[0]);
    cssaddrule(r[0],css);
  });
  $("#a06261_b2").on("click",function()
  {
    let r=findallcss(".a06261 .id1");
    let j=css2json(r[0]);
    j["background-color"]="#f00";
    let css=json2css(j);
    cssdelrule(r[0]);
    cssaddrule(r[0],css);
  });
  $("#a06261_b3").on("click",function()
  {
    let r=findallcss("a06261_a1");
    let kf=getkeyframes(r[0]);
    if (kf.length>=3)
    {
      cssdelkey(kf[0],"50%");
    }
    for (i in kf)
    {
      if (kf[i].key=="0%") break;
    }
    let j=css2json(kf[i]);
    j["background-color"]="#ff0";
    let keystr=json2css(j);
    cssdelkey(kf[i]);
    cssaddkey(kf[i],keystr);

    let k50={cssname:"50%",top:"3em"};
    cssaddkey(kf[0],json2css(k50) );
  });
  $("#a06261_b4").on("click",function()
  {
    let r=findallcss("a06261_a1");
    let kf=getkeyframes(r[0]);
    if (kf.length>=3)
    {
      cssdelkey(kf[0],"50%");
    }
    for (i in kf)
    {
      if (kf[i].key=="0%") break;
    }
    let j=css2json(kf[i]);
    j["background-color"]=null;
    let keystr=json2css(j);
    cssdelkey(kf[i]);
    cssaddkey(kf[i],keystr);
  });

  let o=$(".a06261 .id1");
  o.on("animationend",function()
  {
    let o=$(".a06261 .id1");
    o.css("animation-name",""); 
    setTimeout(function()
    {
      o.css("animation-name","a06261_a1"); 
    },10);

  });
  o.css("animation-name","a06261_a1"); 


//  let r=findallcss();
  let r=findallcss("a06261");
})()

</script>  






4:object
0_[object CSSStyleRule]_.a06261
1_[object CSSStyleRule]_.a06261 .id1
2_[object CSSKeyframesRule]_a06261_a1

沒有留言:

張貼留言