1

我正在构建一个单页网站,我试图通过动画出当前内容然后在新内容中动画化来在部分之间导航。我已经通过使用 setTimeout() 来解决这个问题,即。在 500 毫秒内对当前内容进行动画处理,然后使用 setTimeout() 将新内容的动画延迟到 500 毫秒后。

问题是我发现 setTimeout() 是不可靠的,并且宁愿有一个回调或一些允许我仅在以前的内容已被删除时才能在新内容中制作动画的东西。

我意识到这可以通过使用 animate() 中的回调函数来完成,但是由于我所有的代码都是嵌套的方式,我发现任何接管我的工作的人都无法阅读它。理想情况下,我希望回调位于顶层,而不是嵌套在动画代码深处,因为它更难理解。

仅供参考,我正在使用一个 css3 过渡插件,它将默认的 'animate()' 函数替换为 'transition()' 以使用 css 过渡 - 只是为了避免任何混淆。

这是我到目前为止所拥有的:

相关 HTML

<div id="content">
  <article id="reception">
    <h1 class="title">
      <img src="/images/reception/title.png" alt="Edge" />
    </h1>
    <img src="/images/reception/1.jpg" alt="" class="tile1" />
    <img src="/images/reception/2.jpg" alt="" class="tile2" />
    <img src="/images/reception/hero.jpg" alt="" class="hero" />
    <img src="/images/reception/content1.jpg" alt="" class="content1" />
    <img src="/images/reception/content2.jpg" alt="" class="content2" />
  </article>
  <article id="floorspace">
    <h1 class="title">
      <img src="/images/floorspace/title.png" alt="Space" />
    </h1>
    <img src="/images/floorspace/1.jpg" alt="" class="tile1" />
    <img src="/images/floorspace/2.jpg" alt="" class="tile2" />
    <img src="/images/floorspace/hero.jpg" alt="" class="hero" />
    <img src="/images/floorspace/content1.jpg" alt="" class="content1" />
    <img src="/images/floorspace/content2.jpg" alt="" class="content2" />
  </article>
</div> 

相关脚本:

$(window).bind('hashchange', function (e) {
  if ($(':animated').length) {
    return false;
  }

  var section = $.param.fragment();
  var current = $('#content').children(':visible').attr('id');

  // If this is the first load then load in reception content
  if (section === '') {                    
    if (current === 'reception') {
      animateContentIn("reception");                        
    }
    else {                        
      // Animate out existing content
      animateContentOut(current);

      setTimeout(function () {
        animateContentIn("reception");
      }, 500);
    }
  }
  else {
    // Otherwise find the current page content and animate out
    animateContentOut(current);

    setTimeout(function () {
      animateContentIn(section);
    }, 500);
  }               

  $(window).trigger('hashchange');
});       

function animateContentIn(activePage) { 
  // Now animate in the new content
  switch (activePage) {
    case "floorspace":
      animateFloorspaceElementsIn();
      break;
    case "reception":
      animateReceptionElementsIn();
      break;
  }
}

function animateContentOut(currentPage) {
  // Now animate in the new content
  switch (currentPage) {
    case "floorspace":                    
      animateFloorspaceElementsOut();
      break;
    case "reception":
      animateReceptionElementsOut();
      break;
  }
}

function animateReceptionElementsIn() {
  $('#reception').show();

  $('#reception .title').transition({
    bottom: 520
  }, 200);

  $('#reception .tile1').transition({
    bottom: 504
  }, 300);

  $('#reception .tile2').transition({
    bottom: 504
  }, 350);

  $('#reception .hero').transition({
    bottom: 40
  }, 500);

  $('#reception .content1').transition({
    bottom: 8
  }, 200);

  $('#reception .content2').transition({
    bottom: 8
  }, 250);
}

function animateReceptionElementsOut() {
  $('#reception .title').transition({
    bottom: -56
  }, 200);

  $('#reception .tile1').transition({
    bottom: -136
  }, 300);

  $('#reception .tile2').transition({
    bottom: -152
  }, 350);

  $('#reception .hero').transition({
    bottom: -464
  }, 500, function () {
    $('#reception').hide();
  });

  $('#reception .content1').transition({
    bottom: -112
  }, 200);

  $('#reception .content2').transition({
    bottom: -104
  }, 250);
}

function animateFloorspaceElementsIn() {
  $('#floorspace').show();

  $('#floorspace .title').transition({
    bottom: 520
  }, 200);

  $('#floorspace .tile1').transition({
    bottom: 504
  }, 300);

  $('#floorspace .tile2').transition({
    bottom: 504
  }, 350);

  $('#floorspace .hero').transition({
    bottom: 40
  }, 500);

  $('#floorspace .content1').transition({
    bottom: 8
  }, 200);

  $('#floorspace .content2').transition({
    bottom: 8
  }, 250);
}

function animateFloorspaceElementsOut() {
  $('#floorspace .title').transition({
    bottom: -56
  }, 200);

  $('#floorspace .tile1').transition({
    bottom: -136
  }, 300);

  $('#floorspace .tile2').transition({
    bottom: -152
  }, 350);

  $('#floorspace .hero').transition({
    bottom: -464
  }, 500, function () {
    $('#floorspace').hide();
  });

  $('#floorspace .content1').transition({
    bottom: -132
  }, 200);

  $('#floorspace .content2').transition({
    bottom: -132
  }, 250);
}
4

3 回答 3

1

您是否尝试过使用动画库?像move.js

在结束函数中设置回调函数,它在动画结束时运行。

于 2013-09-06T11:24:24.333 回答
0

您可以尝试使用 jquery 延迟方法。 http://api.jquery.com/delay/

于 2013-09-06T11:22:52.727 回答
0

我知道这是一个非常古老的问题,但如果有人遇到同样的问题,请提供更新的解决方案。

使用 jQueryanimate方法,您可以在动画完成时提供要执行的回调:

$( "#clickme" ).click(function() {
  $( "#book" ).animate({
    opacity: 0.25,
    left: "+=50",
    height: "toggle"
  }, 5000, function() {
    // Animation complete.
  });
});

此外,简单地链接动画将按您的预期工作,您可以使用queue它来访问和管理您创建的链。这里是公开上述内容的官方文档:

https://api.jquery.com/queue/

ps 目前,您使用的所有类型的动画,也可以通过纯 CSS3 解决方案来实现。

于 2017-09-18T01:06:58.267 回答