这是一款效果非常炫酷的jQuery弹性模态窗口导航菜单插件。当一个网站在制作导航菜单时,一般有两种选择:列表形式或模态窗口。该jQuery插件将两者非常完美的结合到了一起,创建了一种带弹性动画效果的模态窗口导航菜单。插件中使用了CSS3 animations 和一些jQuery来制作这种弹性效果的导航菜单。

使用方法

HTML结构

该导航菜单的HTML结构非常简单:使用一个无序列表来制作导航菜单项,它内包裹在一个<nav>元素中,然后<nav>元素元素放置在一个div.cd-bouncy-nav-modal中。

<div class="cd-bouncy-nav-modal">
  <nav>
    <ul class="cd-bouncy-nav">
      <li><a href="#0">Item 1</a></li>
      <!-- other list items here -->
    </ul>
  </nav>
  <a href="#0" class="cd-close">Close modal</a>
</div>
                
CSS样式

在该弹性导航菜单插件中使用了 CSS3 transitionCSS3 animations。默认情况下,导航菜单是被隐藏在窗口下面的(使用translateY(100vh))。当用户点击了.cd-bouncy-nav-trigger按钮时,.cd-bouncy-nav元素被添加上class .fade-in.cd-bouncy-nav元素的透明度和可见性都被改变(这里使用CSS3 transitions来制作平滑的过渡效果)。然后使用cd-move-in来制作导航菜单列表项的动画。

插件中使用CSS animations是为了制作弹性效果,CSS animations可以定义关键帧,这样我们可以灵活的控制动画效果。

为了增加动画效果,插件中使用animation-delay来为不同的导航菜单列表项添加动画延时。

.cd-bouncy-nav-modal {
  position: fixed;
  width: 100%;
  height: 100%;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s 0.6s, visibility 0s 0.9s;
}
.cd-bouncy-nav-modal.fade-in {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.1s 0s, visibility 0s 0s;
}
.cd-bouncy-nav li {
  transform: translateY(100vh);
}
.fade-in .cd-bouncy-nav li {
  animation: cd-move-in 0.4s;
  animation-fill-mode: forwards;
}
@keyframes cd-move-in {
  0% {
    transform: translateY(100vh);
  }
  65% {
    transform: translateY(-1.5vh);
  }
  100% {
    transform: translateY(0vh);
  }
}
                
JAVASCRIPT

该导航菜单插件中使用jQuery来监听.cd-bouncy-nav-trigger元素(或.cd-close元素)的点击事件,为它添加相应的.fade-in/.fade-out class来打开关闭模态窗口。

jQuery(document).ready(function($){
  var is_bouncy_nav_animating = false;
  //open bouncy navigation
  $('.cd-bouncy-nav-trigger').on('click', function(){
    triggerBouncyNav(true);
  });
  //close bouncy navigation
  $('.cd-bouncy-nav-modal .cd-close').on('click', function(){
    triggerBouncyNav(false);
  });
  $('.cd-bouncy-nav-modal').on('click', function(event){
    if($(event.target).is('.cd-bouncy-nav-modal')) {
      triggerBouncyNav(false);
    }
  });

  function triggerBouncyNav($bool) {
    //check if no nav animation is ongoing
    if( !is_bouncy_nav_animating) {
      is_bouncy_nav_animating = true;
      
      //toggle list items animation
      $('.cd-bouncy-nav-modal').toggleClass('fade-in', $bool).toggleClass('fade-out', !$bool).find('li:last-child').one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(){
        $('.cd-bouncy-nav-modal').toggleClass('is-visible', $bool);
        if(!$bool) $('.cd-bouncy-nav-modal').removeClass('fade-out');
        is_bouncy_nav_animating = false;
      });
      
      //check if CSS animations are supported... 
      if($('.cd-bouncy-nav-trigger').parents('.no-csstransitions').length > 0 ) {
        $('.cd-bouncy-nav-modal').toggleClass('is-visible', $bool);
        is_bouncy_nav_animating = false;
      }
    }
  }
});