动态创建和应用CSS3动画

时间:2016-02-03 00:34:35

标签: javascript jquery css css3 css-animations

jQuery中的.animate()函数不允许动画所有CSS3可动画属性(例如,background-color)。是否有一种很好的标准方法可以动态创建,应用和删除页面上元素的CSS3动画?

我目前正在关注示例here,但这很笨拙而且感觉不对。虽然它有效,但我宁愿使用更好的解决方案(使用库或类似的东西)。

1 个答案:

答案 0 :(得分:2)

是的,我们可以动态创建,应用和删除页面中元素的CSS3动画。

要动态创建动画,我们需要使用insertRuleaddRule函数添加@keyframes规则并将其附加到样式表。附加动画后,将其应用于元素非常简单,我们只需要通过内联样式将所需的属性值设置为animation属性。删除它非常简单,我们只需要在需要删除时将值设置为null。

在下面的代码片段中,我首先插入了一个动画并将其应用于加载时的元素。动画开始时,该元素将触发animationstart事件。在这个事件监听器中,我已经获得了动画元素的outerHTML并将其打印出来以显示内联样式是如何存在然后在动画结束时(使用animationend事件监听器),我已删除内联样式并在其后打印outerHTML以显示它不再有动画。

动态创建CSS3动画 没有其他更简单的方法。所有可能的解决方案都涉及使用基本@keyframesinsertRule或关键帧特定addRule函数(用于将规则附加到现有关键帧)创建appendRule并将其附加到样式表)。



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>
&#13;
&#13;
&#13;

此方法可用于动态创建和使用任何类型的动画。以下代码段会创建并添加background-color动画。

&#13;
&#13;
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------------------------------------------------------------------------------";
});
&#13;
.to-animate {
  height: 100px;
  width: 100px;
  margin: 10px;
  background-color: red;
}
&#13;
<div class='to-animate'></div>
<pre class='output'></pre>
&#13;
&#13;
&#13;

跨浏览器版本:

Here是一个跨浏览器版本,支持使用Prefix免费库公开的方法的旧浏览器。这是在IE10 +,Edge,Chrome v50(dev-m),Firefox v43,Opera v35中测试的。在Win 10上的Safari 5.1.7中测试了前缀版本。