Angular js - 幻灯片视图,但不是主页 - ng-animate

时间:2014-01-01 13:15:55

标签: javascript css angularjs slide ng-animate

我正在使用 ng-animate 来滑动应用视图,因此每条路线都会自己滑动视图,这是我的简单代码:

HTML:

<div ng-view ng-animate class="slide"></div>

的CSS:

/*Animations*/
.slide{
  left:0;
}
.slide.ng-enter{
  transition:0.15s linear all;
  position:fixed;
  z-index:inherit;
  left:-100%;
  height:inherit;
}
.slide.ng-leave{
  transition:0.15s linear all;
  position:fixed;
  z-index:9999;
  right:0;
}
.slide.ng-leave-active{
  transition:0.15s linear all;
  position:fixed;
  right:-100%;
  left:100%;
}
.slide.ng-enter-active{
  transition:0.15s linear all;
  left:0;
  position:relative;
}

现在,我想知道, is there anyway to exclude the home page (main "/" route) from sliding?

换句话说:如何从ng-animate中排除路线?

7 个答案:

答案 0 :(得分:7)

那是ng-class的用途。

只要路径发生变化,您就可以设置应用程序范围的变量$ rootScope.path。

app.run(function ($rootScope, $location) {
  $rootScope.$on("$locationChangeStart", function (event, next, current) {
    $rootScope.path = $location.path();
  });
});

然后,您决定按该变量设置动画类

如果您只想在路径不是slide的情况下设置课程/,请执行以下操作

<div ng-view ng-class="{slide: path !== '/' }"></div>

通过这种方式,您无需触摸任何控制器。

完整演示在这里,http://plnkr.co/edit/rmu8oc7ycKzRaA2zv5JN?p=preview

顺便说一句,这使用currant angularJS版本,1.2.7

-------编辑(访问主页后的动画)------

app.run(function ($rootScope, $location) {
  $rootScope.$on("$locationChangeStart", function (event, next, current) {
    if (!$location.path().match(/^\/?$/) && !$rootScope.mainVisitedOnce) {
      $rootScope.mainVisitedOnce = true;
    }
  });
});

<div ng-view ng-class="{slide: mainVisitedOnce }"></div>

http://plnkr.co/edit/QpDFkdKH1kk6ZXy07G5X?p=preview

答案 1 :(得分:4)

演示http://plnkr.co/edit/sMUM48?p=preview

解释

无需创建单独的控制器,指令或更改任何业务逻辑。只需使用.animation方法将条件动画添加到.slide

收听$routeChangeSuccess上的$rootScope活动。这是事件将在动画开始之前触发,因此您有时间相应地设置toRootfromRoot标记。如果目标视图不是“/”视图,则enable-animation类将添加到ng-view元素,因此将执行定义的css过渡。

如果目标视图是“/”视图,则不会执行任何动画。

HTML

<ng-view class="slide"></ng-view>

CSS

.slide {
  position: absolute;
  top: 0;
  width: 100%;
}
.slide div {
  margin: 10px;
  background: red;
}

.slide.enable-animation.ng-enter,
.slide.enable-animation.ng-leave {
  transition: all 10s;
  z-index: 1;
}

.slide.enable-animation.ng-enter {
  left: -100%;
  opacity: 0;
}

.slide.enable-animation.ng-enter.ng-enter-active,
.slide.enable-animation.ng-leave {
  left: 0;
  opacity: 1;
}

.slide.enable-animation.ng-leave.ng-leave-active {
  left: 100%;
  opacity: 0;
}

的JavaScript

app.animation('.slide', function($rootScope, $animate) {

  var toRoot = false;
  var fromRoot = false;

  $rootScope.$on('$routeChangeSuccess', function(event, current, old) {
    toRoot = (current.$$route.originalPath === '/');
    fromRoot = (old.$$route.originalPath === '/');
  });

  return {
    enter: function(element, done) {
      if (!toRoot) {
        element.addClass('enable-animation');
      }
      done();
    },

    leave: function(element, done) {
      if (!fromRoot) {
        element.addClass('enable-animation');
        done();
      } else {
        // set 1000ms timeout to sync with CSS animation
        // otherwise leaving ng-view element will be removed before entering ng-view is in position
        setTimeout(done, 1000);
      }
    }
  }
});

更新1

如果您只是想在第一次加载应用时排除路线,您基本上不需要做任何事情,只需像正常一样定义您的CSS动画。第一个加载的路线不会触发任何动画。

演示http://plnkr.co/edit/uRZyZA?p=preview

答案 2 :(得分:2)

借助@allenhwkim,在rootScope中获取路径。

app.run(function ($rootScope, $location) {
  $rootScope.$on("$locationChangeStart", function (event, next, current) {
    $rootScope.path = $location.path();
  });
});

然后把它作为你的元素:

<div ng-view ng-animate ng-class="{slide: path !== '/' }"></div>
加载的路径不是 .slide时,

/将添加到您的容器元素中。

Here's a working Plunker

答案 3 :(得分:1)

为什么不简单地将class="not-animated"class="animated"这样的根类添加到您不想要或想要动画的控制器中?
通过这种方式,您可以使用.not-animated.animated类在不同的控制器中播放动画。

您可以像这样设置控制器:

<body ng-controller="MainCtrl" ng-class='isAnimated'>
  <div ng-controller="FirstCtrl" ng-class='isAnimated'>Foo</div>
  <div ng-controller="SecondCtrl" ng-class='isAnimated'>Bar</div>
</body>

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.isAnimated = 'not-animated';
});

app.controller('SecondCtrl', function($scope) {
  $scope.isAnimated = 'animated';
});  

这将导致:

<body ng-controller="MainCtrl" ng-class="isAnimated" class="ng-scope not-animated">
    <p class="ng-binding">Hello World!</p>
    <div ng-controller="FirstCtrl" ng-class="isAnimated" class="ng-scope not-animated">Foo</div>
    <div ng-controller="SecondCtrl" ng-class="isAnimated" class="ng-scope animated">Bar</div>   
</body>

DEMO

答案 4 :(得分:1)

您可以构建一个侦听路由更改的控制器并相应地设置一个类。然后,您将能够使用CSS定位正确的动画。

<body ng-controller="TranisitionCtrl" ng-class="currentRoute">
  <div ng-view ng-animate></div>
</body>

app.controller('TranisitionCtrl', function($scope) {
  $scope.$on('$routeChangeStart', function(ev, next, current) { 
    $scope.currentRoute = current.name;
  });
}); 

请注意$ routeChangeStart已更改为$ locationChangeStart以获取更新版本的角度。

我在这里回答了另一个类似的问题Two different animations for route changes

答案 5 :(得分:1)

从动画中排除特定路线的一种方法是使用JS动画包装器来接管ng-view的动画类设置。当你回到非动画路线时,你需要一个额外的类来处理非动画ng-leave

以下是一个示例JS包装器,用于检查路由中的自定义animate属性,以确定路由是否已设置动画:

app.animation('.slider', function($log, $route) {
  return {
    //call done when the animation is over
    enter : function(element, done) {
      if ($route.current.animate) {
        element.addClass("slide ng-enter");
      }
      done();
    },
    leave : function(element, done) {
      if ($route.current.animate) {
        element.addClass("slide ng-leave");
      } else {
        // Need to add non-animated version of ng-leave
        element.addClass("slide ng-leave-noanimation");
      }
      done();
    }
  }
});

这是工作的插件:
http://plnkr.co/edit/ldCy9Cfz2lJWNuLzDIbp?p=preview

答案 6 :(得分:1)

据我所知,你想要的是,如果用户点击你的网站,就不会发生动画。但在那之后,动画应该一直发生。这是我所知道的最短解决方案:

使用模块run方法禁用所有动画:

app.run(function($animate){
    $animate.enabled(false);
});

在绑定到/的控制器中重新启用动画,但延迟了一个摘要周期:

.controller('rootController', function($timeout, $animate){
    $timeout(function(){
        $animate.enabled(true);
    });
})