【问题标题】:CSS animation won't trigger on addClass in jQueryCSS动画不会在jQuery中的addClass上触发
【发布时间】:2014-01-06 05:50:19
【问题描述】:

我有一个非常奇怪的问题。我在 jQuery 中从 JSON 加载文章,当它们加载时,我想为每个动态元素添加一个“动画”类。

$.each(jsonArticles, function (i, article) {

    var $articleHTML = $(
    '<article class="article">' +
        '<a href="' + jsonObject.filmLink + article.reviewLink + '"><img src="' + jsonObject.imagePath + article.reviewImage + '" alt=""></a>' +
        '<h1><a href="' + jsonObject.filmLink + article.reviewLink + '">' + article.reviewTitle + '</a></h1>' +
        '<p><a href="' + jsonObject.filmLink + article.reviewLink + '">' + article.reviewSummary + '</a></p>' +
    '</article>');

    $articles
        .append($articleHTML)
            .find("article")
                .addClass("animate");

});

所有这一切都很好,并且在 Firebug 中检查显示该类已成功添加到每个文章标签。

但是,当尝试在文章上为添加的类使用 CSS 过渡时,它不会动画,而是直接跳到最终样式(不透明度:1)。

.article { 

opacity: 0;

    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;

}

.article.animate { 

    opacity: 1;

}

动画没有发生,但是添加了类并且文章成功设置为不透明度:1.它立即显示。

有人对此有任何想法吗?我根本想不通。

另外一点,这很有趣...如果我将 .animate 类更改为 :hover,那么文章将不会显示,直到我悬停并且动画 确实工作。为什么它适用于悬停而不是立即添加,这对我来说似乎很奇怪。

.article.animate:hover { 

    opacity: 1;

}

如有任何意见,我将不胜感激。

谢谢, 米奇。


现场演示: http://jsfiddle.net/Pz5CD/ 注意文章是如何以 100% 的不透明度弹出的。看不到动画。

【问题讨论】:

  • .delay() 仅适用于 jQuery 动画,因此不会影响添加类。
  • 是的,我的错。我已将其删除。问题仍然存在。

标签: javascript jquery css css-animations


【解决方案1】:

更新:

事实证明,OP 希望按顺序淡入每个元素,这超出了原始问题的范围。我将把我的答案留在这里作为对原始问题的回答。

CSS 动画不会在 jQuery 中的 addClass 上触发

问题是您的新 html 已添加到页面中,并且在应用该 html 的 css 之前添加了 animate 类。为了效率,浏览器会这样跳过。例如,如果您添加一个类,然后将其删除,并重复该过程一百次,则不会有视觉差异。它只会跳到结果。出于这个原因,您必须在元素上强制重绘,以便在添加类之前应用所有以前的样式。我编写了一个函数来处理这个问题,它应该在每个浏览器的任何情况下都可以工作,尽管没有办法保证重绘的行为。它可能会一直有效,而且很高兴拥有!

Live demo here (click).您可以通过将其注释掉并留下addClass()来判断reDraw正在发挥作用。

$('body').append($articleHTML);
$a = $('body').find("article");
reDraw($a).then(function() {
  $a.addClass("animate");
});

function reDraw($element) {
  var deferred = new $.Deferred();
  setTimeout(function() {
    var h = $element[0].offsetHeight;
    var s = $element[0].getComputedStyle;
    deferred.resolve();
  },0);
  return deferred.promise();
}

强制重绘的最佳方法是访问元素的offsetHeightgetComputedStyle。但是,在某些情况下,在某些移动设备上强制重绘失败。为了给重绘添加一些额外的鼓励,我还添加了setTimeout。即使超时时间为 0 也会起作用,但它会抛出调用堆栈,所以我使用一个承诺来确保下一个操作(添加你的类)将在重绘之后发生。这只是意味着您将使用我上面演示的语法来添加类 - redraw($element).then(function() { //your code

为了好玩,我做了一个带和不带 reDraw 的翻转类的小演示。 http://jsbin.com/EjArIrik/1/edit

【讨论】:

  • @MichaelGiovanniPumo 我改变了我的答案。这是一个重绘问题,但单独使用 setTimeout 不一定是最好的方法。
  • 我在这里设置了一个小提琴,说明了我的问题:jsfiddle.net/Pz5CD 我希望每个项目依次淡入。相反,它们只是突然出现,我不明白为什么。
  • @MichaelGiovanniPumo 这是一个快速而混乱的事情 - 它与 css 无关 jsfiddle.net/Au3Vt
  • 或者,您可以只使用 2 个使用相同动画、不同名称的关键帧,并在它们之间来回切换,而不是使用所有这些 js。然后,浏览器会将其视为一个完整的并再次执行它。
  • @kennsorr - 这是一个有趣的建议,也许它会是一个很好的答案。
【解决方案2】:

你需要在元素渲染到 dom 后将类添加到元素中,设置的 timout 可能会起作用

setTimeout(function(){
    $articleHTML.addClass("animate");
}, i * 500 );

http://jsfiddle.net/Pz5CD/1/

【讨论】:

  • 这在元素按顺序添加每个类的意义上是有效的,但它不会动画。它只是立即从 0 不透明度变为 1。真的很奇怪。
  • 虽然您的演示有效,但我认为您确实需要在每个循环中使用它来查看我的问题。在循环中添加动态 HTML 元素并在其后添加类。
  • @MichaelGiovanniPumo 提供现场演示,重现您的问题供我们查看。
  • 在此处查看此小提琴:jsfiddle.net/Pz5CD 请注意文章如何简单地“弹出”到不透明度 1,而不是按照 CSS 淡入?
  • @m59 是的,淡入淡出有效,但我在让每个淡入淡出之后。 1,淡出,然后 2 淡出……等等。这可能吗?
猜你喜欢
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2018-03-02
  • 1970-01-01
相关资源
最近更新 更多