【问题标题】:Dynamically create and apply CSS3 animations动态创建和应用 CSS3 动画
【发布时间】:2016-02-07 13:31:01
【问题描述】:

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

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

【问题讨论】:

  • 看看bounce.js
  • 这并没有提到背景颜色或 jquery 还不能做的其他事情。我错过了什么还是bounce.js 是jquery.animate() 的不同实现?
  • 你可以只使用 addClass 和 removeClass 并在你的 css 中设置你的动画吗?
  • 动画本身需要是动态的

标签: javascript jquery css css-animations


【解决方案1】:

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

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

在下面的 sn-p 中,我首先插入了一个动画并将其应用于加载的元素。当动画开始时,元素触发animationstart 事件。在此事件侦听器中,我获得了正在动画的元素的 outerHTML 并将其打印以显示内联样式的存在方式,然后在动画结束时(使用 animationend 事件侦听器),我'我们删除了内联样式并在其后打印了outerHTML,以显示它不再有动画。

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

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>

此方法可用于动态创建和使用任何类型的动画。在 sn-p 下面创建并添加一个background-color 动画。

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>

跨浏览器版本:

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

【讨论】:

  • 我喜欢这个。 +1 唯一缺少的是跨浏览器支持。 (或者至少是支持 CSS3 的浏览器的供应商前缀。)您可以为此使用 David 的另一个 sn-p:detect vendor prefix
  • @BramVanroy:非常感谢。实际上,我在是否使用 David 的脚本(或)使用无前缀之类的库并让他们找出浏览器所需的前缀之间纠结。我想我会走第二条路线以避免更多地膨胀代码(但您的评论绝对有价值)。
  • 我不知道 PrefixFree 能够在 DOM 更改/样式规则插入后添加供应商前缀,但我查了一下,你确实是对的! (可能需要its plugin 才能正常工作。)
  • 是的@BramVanroy,它还公开了一个变量(PrefiFree.prefix),我们可以使用它来获取适用于用户浏览器的前缀。
  • @BramVanroy:This 就是我所说的。使用 Prefix free 的公开函数和变量。在所有浏览器中都经过测试和工作(前缀测试是在旧版本的 Safari 中完成的)。
猜你喜欢
  • 2014-03-02
  • 1970-01-01
  • 2011-12-30
  • 1970-01-01
  • 2013-07-12
  • 2017-11-03
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
相关资源
最近更新 更多