我觉得我在这里做了很多错事。我有一个有3种状态的视图 - 称它们为intro,加载和完成。我希望每个州随着用户的进展从左向右滑动。
这是基本结构:
var app = angular.module('plunker', ['ngAnimate']);
app.controller('MainCtrl', function($scope) {
$scope.triggered = '';
$scope.loading = false;
$scope.completed = false;
$scope.one = function() {
console.log('one');
$scope.loading = true;
$scope.completed = false;
};
$scope.two = function() {
$scope.loading = false;
$scope.completed = true;
};
}).directive('inheritHeight', ['$window', '$timeout', function($window, $timeout) {
return {
restrict: 'A',
link: function (scope, elm, attrs) {
scope.$watch("loading", function(newV, oldV) {
console.log(newV, elm[0]);
$timeout(function () {
scope.triggered = scope.triggered + 'triggered ';
scope.height = elm[0].querySelector('.child').offsetHeight;
console.log(elm[0].querySelector('.child'));
console.log(elm[0].querySelector('.child').offsetHeight);
elm.css('height', elm[0].querySelector('.child').offsetHeight + 'px');
});
});
}
};
}]);
.parent {
border: 1px solid red;
position: relative;
overflow: hidden;
}
.child {
width: 100%;
position: absolute;
top: 0;
left: 0; }
.child.ng-enter, .child.ng-leave {
-webkit-transition: 800ms cubic-bezier(0.645, 0.045, 0.355, 1) all;
-moz-transition: 800ms cubic-bezier(0.645, 0.045, 0.355, 1) all;
-ms-transition: 800ms cubic-bezier(0.645, 0.045, 0.355, 1) all;
-o-transition: 800ms cubic-bezier(0.645, 0.045, 0.355, 1) all;
transition: 800ms cubic-bezier(0.645, 0.045, 0.355, 1) all; }
.child.ng-enter {
-webkit-transform: translateX(100%);
-moz-transform: translateX(100%);
-ms-transform: translateX(100%);
-o-transform: translateX(100%);
transform: translateX(100%); }
.child.ng-enter.ng-enter-active {
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-ms-transform: translateX(0);
-o-transform: translateX(0);
transform: translateX(0); }
.child.ng-leave {
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-ms-transform: translateX(0);
-o-transform: translateX(0);
transform: translateX(0); }
.child.ng-leave.ng-leave-active {
-webkit-transform: translateX(-100%);
-moz-transform: translateX(-100%);
-ms-transform: translateX(-100%);
-o-transform: translateX(-100%);
transform: translateX(-100%); }
.child-a {
background-color: green;
height: 100px;
}
.child-b {
background-color: blue;
height: 50px;
}
.child-c {
background-color: yellow;
height: 30px;
}
<script src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-animate.js"></script>
<div ng-app="plunker" ng-controller="MainCtrl">
<div class="parent" inherit-height="">
<div class="child child-a" ng-if="!loading && !completed">
<button ng-click="one()">Click One</button>
</div>
<div class="child child-b" ng-if="loading && !completed">
<button ng-click="two()">Click Two</button>
</div>
<div class="child child-c" ng-if="!loading && completed"></div>
</div>
<p>{{ height }}</p>
<p>{{ triggered }}</p>
</div>
当新状态进入视图时,具有inherit-height
指令的父div似乎不能正确更新其高度,即使它位于scope.$watch
和$timeout
之内......
有什么建议吗?谢谢!
答案 0 :(得分:0)
在制作有关动画和CSS的任何内容之前,您需要提前知道两件事:
在您的示例中,status.loading
指向任何内容。由于您未将隔离范围分配给inherit-height
指令,因此其范围将与其父级相同,在您的情况下为MainCtrl
。但是,您从未注册$scope.status.loading
之类的内容,因此观察者无所事事,这就是为什么$timeout
服务中的所有逻辑都无法正常工作的原因。
所以elm[0]
没有任何意义。可以通过像elm.eq(0).height()
这样的目标实现同样的目标。
querySelector
只会返回匹配所以在你的情况下,它总是会选择child-a
,可能不是你想要的。以这种方式获得子元素的高度通常也是一种不好的做法。如果确实需要,创建另一个指令并从父级中获取它会更好。
我建议你在制作其他复杂的css部分之前检查angular document或其他教程的指令范围和链接功能的想法。
答案 1 :(得分:0)
所以我希望querySelector工作,因为ng-if从DOM中删除元素,但是,似乎并非如此。定位要转换的子元素可以解决问题:
elm.css('height', elm[0].querySelector('.child.ng-enter').offsetHeight + 'px');