【问题标题】:CSS Animation won't apply for the second timeCSS动画不会第二次申请
【发布时间】:2016-09-10 01:39:18
【问题描述】:

我目前遇到了 CSS 动画问题。从数组中调用随机背景,显示和更改等等。我为图片说明 id 应用了两个动​​画,一个滑入和一个延迟滑出。第一次滑入滑出运行良好,但是当第二个背景出现时,标题只是出现在屏幕上,没有任何动画。

This is my test page 及以下是我的代码。

HTML 代码:

<script type="text/javascript">

function loadRandomImage(imgs) {
    var index = Math.floor(Math.random() * imgs.length);

    console.log("loadRandomImages(): index = "+ index);

    $.backstretch(imgs[index].url, {duration: 30000, fade: 1200});  
    $("#caption").html(imgs[index].caption);
}

var images = new Array(); //array of imgs objects

images[0] = {url: "https://s-media-cache-ak0.pinimg.com/736x/a5/47/45/a5474577f4a4ae93c85db719d0cbafd4.jpg", caption: "Caption0"};
images[1] = {url: "https://s-media-cache-ak0.pinimg.com/736x/e6/41/74/e64174e355f78a0f07e951bcec62ca96.jpg", caption: "Caption1"};
images[2] = {url: "https://media.giphy.com/media/3o7abHrsGbV10rCeze/giphy.gif", caption:"Caption2"};
images[3] = {url: "https://media.giphy.com/media/Bbt5FxRiArl3a/giphy.gif", caption:"Caption3"};

// Preload

setTimeout(loadRandomImage, 1000, images);

// Change images every 3 seconds

setInterval(loadRandomImage, 30000, images);

</script>


<div id="pattern"></div>
<div id="pattern2"></div>

<div id="caption"></div>

CSS 代码:

#caption {
    position: relative;
    font: 1.5em Trebuchet, sans-serif;
    text-align: center;
    margin-left: 75%;
    z-index: 56;
    color: #ffffff;
    background: rgba(0, 0, 0, 0.7);
    padding: 8px;
    animation: slidein 3s, slideout 3s 27s;
}

#caption:empty
{
    display: none;
}

@keyframes slidein {
  0% {
    margin-left: 100%;
    width:100%;
    visibility:hidden;
    opacity: 0; 
  }

  100% {
    margin-left: 75%;
    width:100%;
    opacity: 1;
    visibility:visible;
  }
}

@keyframes slideout {
  0% {
    margin-left: 75%;
    width:100%;
    opacity: 1;
    visibility:visible;
  }

  100% {
    margin-left: 100%;
    width:100%;
    opacity:0;
    visibility:hidden;
  }
}

【问题讨论】:

    标签: html css animation css-animations


    【解决方案1】:

    当没有为该属性指定值时,CSS 动画的迭代次数 (animation-iteration-count) 仅为 1。由于您没有指定任何值,因此动画只执行一次(即在页面加载时)。动画完成循环后,没有纯 CSS 方法可以重新触发动画。它必须从元素中移除,然后重新附加才能重新开始。

    因此,对于您的情况,您必须执行以下操作 - (a) 在页面加载时使用 JS 在 #caption 上设置动画,因为这样可以更轻松地删除和重新添加它们 (b) 完成后slideout 动画,从元素中删除两个动画(即设置animation-name: none)并将#captionhtml 设置为无,因为:empty 选择器只会隐藏它。 (c) 在元素上设置下一个图像后(使用loadRandomImage 函数),将动画设置回元素上。这将重新触发动画,因此在每次图像切换期间,标题都会滑入和滑出。

    注意:我已经更改了 HTML 和 JS 中与此答案无关的一些部分(例如删除两个 div 并将它们替换为 1,避免使用 $.backstretch 和使用css()等加载图像。但这些只是辅助项,不会影响这个答案的关键(即删除和添加动画)。

    function loadRandomImage(imgs) {
      var index = Math.floor(Math.random() * imgs.length);
    
      $('#img').css('background-image', 'url(' + images[index].url + ')');
      $('#caption').css({
        'animation-name': 'slidein, slideout',
        'animation-duration': '3s, 3s',
        'animation-delay': '0s, 7s'
      });
      $("#caption").html(imgs[index].caption);
    }
    
    var images = new Array(); //array of imgs objects
    
    images[0] = {
      url: "http://lorempixel.com/100/100/nature/1",
      caption: "Caption0"
    };
    images[1] = {
      url: "http://lorempixel.com/100/100/nature/2",
      caption: "Caption1"
    };
    images[2] = {
      url: "http://lorempixel.com/100/100/nature/3",
      caption: "Caption2"
    };
    images[3] = {
      url: "http://lorempixel.com/100/100/nature/4",
      caption: "Caption3"
    };
    
    // Preload
    
    setTimeout(loadRandomImage, 1000, images);
    
    
    $('#caption').on('animationend', function(e) {
      if (e.originalEvent.animationName == 'slideout') {
        $('#caption').css('animation-name', 'none');
        $('#caption').html('');
        setTimeout(function() { /* dummy timeout to make sure browser sees animation as none before adding it again */
          loadRandomImage(images);
        }, 0);
      }
    });
    #caption {
      position: relative;
      font: 1.5em Trebuchet, sans-serif;
      text-align: center;
      margin-left: 75%;
      z-index: 56;
      color: #ffffff;
      background: rgba(0, 0, 0, 0.7);
      padding: 8px;
    }
    #caption:empty {
      display: none;
    }
    @keyframes slidein {
      0% {
        margin-left: 100%;
        width: 100%;
        visibility: hidden;
        opacity: 0;
      }
      100% {
        margin-left: 75%;
        width: 100%;
        opacity: 1;
        visibility: visible;
      }
    }
    @keyframes slideout {
      0% {
        margin-left: 75%;
        width: 100%;
        opacity: 1;
        visibility: visible;
      }
      100% {
        margin-left: 100%;
        width: 100%;
        opacity: 0;
        visibility: hidden;
      }
    }
    /* Just for demo */
    
    #img {
      height: 100px;
      width: 100px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="img"></div>
    <div id="caption"></div>

    animationend 事件在某些浏览器中仍需要供应商前缀。

    【讨论】:

    • 感谢 Harry 的帮助和修改我的代码,以便其他人也可以从中学习!它工作得几乎完美。只是一个小问题:预加载效果很好,选择随机图像,标题滑入和滑出,但是当加载第二张图像时,标题就没有出现。奇怪,因为从第三张图片开始,它又完美地工作了。我猜预加载后发生了一些事情。有什么建议吗?
    • @mr_Jezy:不客气。很高兴我能帮上忙。您强调的问题似乎有点时间问题,因此我将loadRandomImage 函数的调用也移到了animationend 事件中。超时(0 秒)只是为了确保在单个阻塞调用中不会发生删除和重新添加(否则浏览器根本看不到任何变化,因此不会重新触发动画) .如果有帮助,请将答案标记为已接受。努力得到认可总是很高兴:D
    【解决方案2】:

    你需要使用一个回调,这里解释:

    How do create perpetual animation without freezing?

    【讨论】:

      【解决方案3】:

      我认为动画方向需要改变。

      这些是可能性:

      animation-direction: normal|reverse|alternate|alternate-reverse|initial|inherit;
      

      我认为您需要执行以下操作之一:

      替代 动画将在每个奇数时间(1,3,5 等)正常播放,并在每个偶数时间(2,4,6 等...)反向播放

      交替反向 动画将在奇数时间(1,3,5等)反向播放,偶数时间(2,4,6等...)以正常方向播放

      目前设置为

      animation-direction: initial, initial;
      

      在这里看到:http://www.w3schools.com/cssref/css3_pr_animation-direction.asp

      【讨论】:

      • 感谢您的建议,我都尝试了,但似乎不起作用。
      • 是否可以制作 .capOne 和 .capTwo 并为 .capOne 使用 slidein 为 .capTwo 使用 slideout?
      【解决方案4】:

      您可以直接使用 CSS 解决方案,而不是已经提供的 Javascript 建议。

      • 只需将animation-iteration-count 设置为“无限”(以连续交替两个元素,或设置重复次数的整数)

      如果你想要交错/交替的动画:

      • 在第二个元素上使用animation-delay(匹配animation-duration),这样它在第一个元素动画完成之前不会出现
      • 在动画结束时设置延迟(恢复到原始状态 @ 50%),以便第一个元素在第二个动画时保持隐藏。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多