Search code examples
javascriptcssinternet-explorerstylesheet

I get Invalid argument error when try to addRule to stylesheet in ie


I am trying to dynamically remove a rule and then add a new one in it's place, to get a calculated animation for a dynamically changing div innerHTML.

var ss = document.styleSheets ;           
for(j=0;j<ss[0].cssRules.length;j++)
if(ss[0].cssRules[j].name == "slide")
{  
ss[0].deleteRule(j);                              
break;
}  
ss[0].addRule('@keyframes slide', 'from {top:0px;} to {top:-300px;}', 0);

The code above should remove a css animation and insert a new one. The problem is with the '@' character, if I remove it code passes, but then it's not an animation for ie cause it doesn't have the '@keyframes' identifier. The reason I am going about this in such a manner is because you don't have variables in css for ie11, and you cannot alter stylesheet csstext! So I thought delete the whole rule and insert a new one. All I'm trying to do is dynamically change this rule:

@keyframes slide { 
     from {top:0px;}  
     to   {top:-100px;}
}

To this rule for example:

@keyframes slide { 
     from {top:0px;}  
     to   {top:-300px;}
}

It is really a pain in the neck to try and deal with ie's special world!! Thanks for your help.


Solution

  • I've tested your code and tried to find why it not works in IE. But I could not find a good reason for this. It seems like what you've mentioned that IE could not read the keywork with @. I've just found a workaround for this is to customize a funcition to add the attribute. Here is my working demo.

    CSS

    <style>
        div {
            margin-top: 500px;
            width: 100px;
            height: 100px;
            background: red;
            position: relative;
            animation: mymove 5s infinite;
        }
    
        @keyframes mymove {
            from {
                top: 0px;
            }
    
            to {
                top: 200px;
            }
        }
    </style>
    

    HTML

    <script>
        function insertStyleSheetRule(ruleText) {
            let sheets = document.styleSheets;
            if (sheets.length == 0) {
                let style = document.createElement('style');
                style.appendChild(document.createTextNode(""));
                document.head.appendChild(style);
            }
            let sheet = sheets[sheets.length - 1];
            sheet.insertRule(ruleText, sheet.rules ? sheet.rules.length : sheet.cssRules.length);
        }
        insertStyleSheetRule("@keyframes mymove{from {top:0px;} to {top:-300px;}}");
        insertStyleSheetRule("div {margin-top: 500px;width: 100px;height: 100px;background: red;position: relative; animation: mymove 5s infinite;- webkit - animation: mymove 5s infinite;}");
    </script>