简体   繁体   中英

Dynamically create and apply CSS3 animations

The .animate() function in jQuery does not allow all CSS3 animatable properties to be animated (for example, background-color ). Is there a nice, standard way to dynamically create, apply, and remove CSS3 animations to elements on the page?

I'm currently following the example here but this is clunky and feels wrong. While it works, I would rather a better solution (using a library or something like that).

Yes, we can dynamically create, apply and remove CSS3 animations to an element in the page.

To dynamically create an animation, we need to use the insertRule or addRule functions to add the @keyframes rules and append it to the stylesheet. Once the animation is appended, applying it to the element is very simple, we just need to set the required property value to the animation property via inline styles. Removing it agian is very simple, we just need to set the value back to null when it needs to be removed.

In the below snippet, I have first inserted an animation and applied it to the element on load. When the animation starts, the element fires the animationstart event. Within this event listener, I've obtained the outerHTML of the element that is being animated and printed it to show how inline style is present and then at the end of the animation (using the animationend event listener), I've removed the inline style and printed the outerHTML after it to show how it no longer has the animation.

There are no other simpler ways to dynamically create CSS3 animations . All possible solutions will involve creating and appending @keyframes to the stylesheets using basic insertRule , addRule or the keyframes specific appendRule function (which is used to append rules to an existing keyframe).

 var elm = document.querySelector('.to-animate'); var op = document.querySelector('.output'); var animName = "shake-up-down", animDuration = "3s", animTiming = "linear", animFillMode = "forwards", animIteration = "3"; var ruleText = "0% {transform: translateY(0px);}"; ruleText += "25% {transform: translateY(10px);}"; ruleText += "75% {transform: translateY(-10px);}"; ruleText += "100% {transform: translateY(0px);}"; /* From David Walsh's blog */ function addCSSAnimRule(sheet, name, rules, index) { if ("insertRule" in sheet) { sheet.insertRule("@keyframes " + name + "{" + rules + "}", index); } else if ("addRule" in sheet) { sheet.addRule("@keyframes " + name, rules, index); } } /* Self written */ function applyAnimation(elm, name, duration, timing, iteration, fillmode) { elm.style["animation"] = name + " " + duration + " " + timing + " " + iteration + " " + fillmode; /* or if you want to set them individually, comment the above line and uncomment this elm.style["animationName"] = name; elm.style["animationDuration"] = duration; elm.style["animationTimingFunction"] = timing; elm.style["animationIterationCount"] = iteration elm.style["animationFillMode"] = fillmode;*/ } addCSSAnimRule(document.styleSheets[0], animName, ruleText, 0); applyAnimation(elm, animName, animDuration, animTiming, animIteration, animFillMode); /* to print output */ elm.addEventListener("animationstart", function(e) { op.textContent = "Animation " + e.animationName + " has started."; op.textContent += "\\n\\nElement's Outer HTML: \\n"; op.textContent += elm.outerHTML; op.textContent += "\\n\\n------------------------------------------------------------------------------"; }); elm.addEventListener("animationend", function(e) { elm.removeAttribute("style"); /* remove the animation */ op.textContent += "\\nAnimation " + e.animationName + " has ended."; op.textContent += "\\n\\nElement's Outer HTML: \\n"; op.textContent += elm.outerHTML; op.textContent += "\\n\\n------------------------------------------------------------------------------"; }); 
 .to-animate { height: 100px; width: 100px; margin: 10px; border: 1px solid red; } 
 <div class='to-animate'></div> <pre class='output'></pre> 


This method can be used to dynamically create and use any type of animation. Below snippet creates and adds a background-color animation.

 var elm = document.querySelector('.to-animate'); var op = document.querySelector('.output'); var animName = "bgColor", animDuration = "4s", animTiming = "linear", animFillMode = "forwards", animIteration = "3"; var ruleText = "0% {background-color: red;}"; ruleText += "25% {background-color: orange;}"; ruleText += "50% {background-color: yellow;}"; ruleText += "75% {background-color: pink;}"; ruleText += "100% {background-color: red;}"; /* From David Walsh's blog */ function addCSSAnimRule(sheet, name, rules, index) { if ("insertRule" in sheet) { sheet.insertRule("@keyframes " + name + "{" + rules + "}", index); } else if ("addRule" in sheet) { sheet.addRule("@keyframes " + name, rules, index); } } /* Self written */ function applyAnimation(elm, name, duration, timing, iteration, fillmode) { elm.style["animation"] = name + " " + duration + " " + timing + " " + iteration + " " + fillmode; /* or if you want to set them individually, comment the above line and uncomment this elm.style["animationName"] = name; elm.style["animationDuration"] = duration; elm.style["animationTimingFunction"] = timing; elm.style["animationIterationCount"] = iteration elm.style["animationFillMode"] = fillmode;*/ } addCSSAnimRule(document.styleSheets[0], animName, ruleText, 0); applyAnimation(elm, animName, animDuration, animTiming, animIteration, animFillMode); /* to print output */ elm.addEventListener("animationstart", function(e) { op.textContent = "Animation " + e.animationName + " has started."; op.textContent += "\\n\\nElement's Outer HTML: \\n"; op.textContent += elm.outerHTML; op.textContent += "\\n\\n------------------------------------------------------------------------------"; }); elm.addEventListener("animationend", function(e) { elm.removeAttribute("style"); /* remove the animation */ op.textContent += "\\nAnimation " + e.animationName + " has ended."; op.textContent += "\\n\\nElement's Outer HTML: \\n"; op.textContent += elm.outerHTML; op.textContent += "\\n\\n------------------------------------------------------------------------------"; }); 
 .to-animate { height: 100px; width: 100px; margin: 10px; background-color: red; } 
 <div class='to-animate'></div> <pre class='output'></pre> 


Cross Browser Version:

Here is a cross browser version with support for older browsers using methods exposed by the Prefix free library. This was tested in IE10+, Edge, Chrome v50 (dev-m), Firefox v43, Opera v35. Testing for prefixed version was done in Safari 5.1.7 on Win 10.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM