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

时间:2014-01-05 20:17:52

标签: javascript jquery css css3 css-animations

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

$.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;

}

我很感激任何意见。

谢谢, MIKEY。


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

2 个答案:

答案 0 :(得分:8)

更新

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

CSS动画不会在jQuery

中的addClass上触发

问题是您的新html已添加到页面中,并且在应用该html的css之前添加了animate类。为了提高效率,浏览器会像这样跳过。例如,如果您添加了一个类,然后将其删除,并重复该过程一百次,则不会产生视觉差异。它会跳过结果。因此,您必须强制重新绘制元素,以便在添加类之前应用所有先前的样式。我写了一个函数来处理这个问题,它应该适用于每个浏览器的每个环境,尽管没有办法保证reDraw的行为。它可能永远有效,而且很高兴!

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也会有效,但它会抛出调用堆栈,因此我使用一个promise来确保重绘后会发生下一个操作(添加类)。这只是意味着您将使用我上面演示的语法来添加类 - redraw($element).then(function() { //your code

为了好玩,我做了一个关于在有和没有reDraw的情况下翻转课程的小演示。的 http://jsbin.com/EjArIrik/1/edit

答案 1 :(得分:5)

在将元素渲染到dom后,需要将该类添加到元素中,设置时间可能有效

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

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