title: Dynamically Changing Keyframe CSS Firefox
body: <p>While looking at this question <a href="https://stackoverflow.com/questions/10342494/set-webkit-keyframes-values-using-javascript-variable">Set Webkit Keyframes Values Using Javascript Variable</a>
  The accepted answer is a Webkit specific way to change key-frame CSS dynamically i decided to see if i could change it around so that it would work in Firefox. </p>
  
  <p>I managed to get this working <a href="http://jsfiddle.net/RHhBz/333/" rel="nofollow noreferrer">JSFiddle</a> which works as it should except for the fact that sometimes the animation wont start. About 1/4 of clicks will start the animation but the other 3/4 will cause nothing to happen.</p>
  
  <p>Can someone explain to me what exactly is happening? have i missed something simple or is there a race condition somewhere that i am not accounting for?</p>
  
  <p><strong>HTML</strong></p>
  
  <pre><code>&lt;div id="box"&gt;&lt;/div&gt;
  
  &lt;div id="update-box"&gt;Run Another Animation&lt;/div&gt;
  </code></pre>
  
  <p><strong>CSS</strong></p>
  
  <pre><code>@-webkit-keyframes rotate {
      0% {-webkit-transform: rotate(-10deg);}
      100% {-webkit-transform: rotate(10deg);}
  }
  @keyframes rotate {
      0% {-moz-transform: rotate(-10deg);}
      100% {-moz-transform: rotate(-10deg);}
  }
  body { text-align: center; }
  #box {
          height: 100px;
          width: 100px;
          background-color: blue;
          -webkit-animation-duration: 1s;
          -webkit-animation-timing-function: linear;
          -webkit-animation-name: "rotate";
          animation-duration: 1s;
          animation-timing-function: linear;
          animation-name: "rotate";
          margin: 30px auto;
  }
  
  #update-box {
      border: 3px solid black;
      background: #efefef;
      font-weight: bold;
      cursor: pointer;   
      padding: 10px;
      margin: 30px auto;
      display: inline-block;
  }
  #update-box:hover {
      background: black;
      color: white;
  }
  </code></pre>
  
  <p><strong>JS</strong></p>
  
  <pre><code>// search the CSSOM for a specific -webkit-keyframe rule
  function findKeyframesRule(rule) {
      // gather all stylesheets into an array
      var ss = document.styleSheets;
  
      // loop through the stylesheets
      for (var i = 0; i &lt; ss.length; ++i) {
  
          // loop through all the rules
          for (var j = 0; j &lt; ss[i].cssRules.length; ++j) {
              // find the -webkit-keyframe rule whose name matches our passed over parameter and return that rule
              if ((ss[i].cssRules[j].type == window.CSSRule.KEYFRAMES_RULE) &amp;&amp; ss[i].cssRules[j].name == rule) return [ss[i], ss[i].cssRules[j]];
          }
      }
  
      // rule not found
      return null;
  }
  
  // remove old keyframes and add new ones
  function change(anim) {
      // find our -webkit-keyframe rule
      var results = findKeyframesRule(anim);
      var style_sheet = results[0];
      var rule = results[1];
      console.log(rule)
      // remove the existing 0% and 100% rules
      rule.deleteRule("0%");
      rule.deleteRule("100%");
      rule.appendRule("0% { -moz-transform: rotate(0deg);}")
      rule.appendRule("100% { -moz-transform: rotate(" + randomFromTo(-360, 360) + "deg); }")
  
      // create new 0% and 100% rules with random numbers
  
      // assign the animation to our element (which will cause the animation to run)
      document.getElementById('box').style.animationName = anim;
  }
  
  // begin the new animation process
  function startChange() {
      // remove the old animation from our object
      document.getElementById('box').style.animationName = "none";
  
      // call the change method, which will update the keyframe animation
      setTimeout(function () {
          change("rotate");
      }, 0);
  }
  
  // get a random number integer between two low/high extremes
  function randomFromTo(from, to) {
      return Math.floor(Math.random() * (to - from + 1) + from);
  }
  
  $(function () {
      $('#update-box').bind('click', click_handler);
  });
  
  function click_handler(e) {
      e.preventDefault();
      startChange();
  }
  </code></pre>