ng-hide CSS 이행이 완료될 때까지 요소를 표시하지 않습니까?
간단한 질문이지만 구현에 문제가 있습니다.다음과 같은 DOM 설정이 있는 경우:
<h1 class="fade" ng-repeat="child in parent.children" ng-show="parent.activeChild== child ">@{{ child.title }}</h1>
?activeChild의 of의 parent모델 변경, 모델이 변경되기 전에 현재 활성 상태인 아이를 페이드아웃하고 변경 후 새로 활성 상태인 아이를 페이드아웃하려면 어떻게 해야 합니까?
CSS 이행만으로 대략적으로 동작하고 있습니다.
.fade.ng-hide-add {
transition:opacity 1s ease;
}
.fade.ng-hide-remove {
transition:opacity 1s ease 1s;
}
.fade.ng-hide-add {
opacity:1;
&.ng-hide-add-active {
opacity:0;
}
}
.fade.ng-hide-remove {
opacity:0;
&.ng-hide-remove-active {
opacity:1;
}
}
단, 이로 인해 이 문제가 발생합니다(Plunkr).
기본적으로, 저는 제 애니메이션을 체인하고 싶습니다.ng-animate 문서를 읽어보려고 했지만 원하는 효과를 전달하는데 필요한 구문에 문제가 있습니다.
Angular docs에서 이런 걸 본 적이 있어요.
app.animation('.fade', [function() {
return {
addClass: function(element, className, doneFn) {
},
removeClass: function(element, className, doneFn) {
}
};
}]);
- 죠?
className? 페이드인/페이드아웃하면서 신청하는 클래스입니까?가가기 기대 ?? ??? - 죠?
doneFn애니메이션이 완성되면 실행되는 기능인가?가들 ?? - 하면 요?
addClass★★★★★★★★★★★★★★★★★」removeClass경우, 이미 「」가 되어 있는 는,doneFn
목표
Angular의 ngAnimate 모듈을 사용하여 CSS 또는 JS에서 직접 작업 애니메이션을 생성하고 싶습니다.어떻게 하면 좋을까요?
왜 따로 쓰세요?<h1>각 제목에 대해. 한 에 쓸 수 요.<h1>태그를 지정하여 제목을 표시합니다.
당신의 문제에 대한 데모를 작성했고, 당신의 요구 사항을 성공적으로 완료했습니다.
갱신필
": " "를 되어 있습니다.ngAnimate★★★★★★★★★★를 사용하는 경우ngAnimate '클래스', '클래스', '클래스'가 됩니다..ng-hide 요소를 숨깁니다.
여기 앱용 컨트롤러가 있습니다.
app2.controller("testController", ["$scope", "$timeout", function ($scope, $timeout) {
$scope.heading = {};
$scope.heading.show = true;
$scope.parent = {};
$scope.parent.children = ["A", "B", "C", "D"];
$scope.parent.activeChild = "A";
$scope.changeHeading = function (child) {
$timeout(function () {
$scope.parent.activeChild = child;
$scope.heading.show = true;
}, 1000);
}
}]);
그리고 당신의 html 페이지는 이렇게 되어 있어야 합니다.
<div ng-controller="testController">
<h1 class="myAnimateClass" ng-show="heading.show" ng-class="{fadeIn : heading.fadeInModel==true, fadeOut : heading.fadeOutModel}"> {{parent.activeChild}} </h1>
<p ng-repeat="child in parent.children" ng-click="heading.show = false;changeHeading(child)">{{child}}</p>
</div>
CSS3를 사용하여 페이드인 및 페이드아웃 애니메이션을 구현했습니다.
.myAnimateClass {
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
-ms-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
opacity:1;
}
.myAnimateClass.ng-hide {
opacity: 0;
}
설명.
하기 위해 신신요 to to to, to는 to to to 했습니다.ng-class ★★★★★★★★★★★★★★★★★」$timeout J자단위로JS.
저는 요.<h1>태그를 지정하여 제목을 표시합니다. 돼요.$scope.parent.activeChild
두 변수를 했습니다.$scope.heading.fadeOutModel ★★★★★★★★★★★★★★★★★」$scope.heading.fadeInModel를 및 fadeIn ★★★★★★★★★★★★★★★★★」fadeOut역동적으로
할 때 했습니다.fadeOut당신의 표제까지.js app.js의 기능을 했습니다.changeHeading().
.1000페이드 아웃 애니메이션을 완료하는 데 밀리초입니다.이 지나면 새합니다.fadeIn그래서 페이드인 애니메이션을 시작합니다.
도움이 되길 바랍니다!!!
선택에 따라 특정 요소를 표시하는 보다 ng-animate한 방법은 다음을 사용하는 것입니다.ngSwitch이 지시어는 스코프식을 기반으로 템플릿의 DOM 구조를 조건부로 스왑하기 위해 사용됩니다.여기 예가 있습니다.
HTML
<button ng-repeat="item in items" ng-click="parent.selection = item">{{ item }}</button>
<div class="animate-switch-container" ng-switch on="parent.selection">
<div class="animate-switch" ng-switch-when="foo">foo</div>
<div class="animate-switch" ng-switch-when="bar">bar</div>
</div>
자바스크립트
$scope.items = ['foo', 'bar'];
$scope.parent = {
selection: $scope.items[0]
}
CSS
.animate-switch-container {
position:relative;
height:40px;
overflow:hidden;
}
.animate-switch {
padding:10px;
}
.animate-switch.ng-animate {
transition:opacity 1s ease;
}
.animate-switch.ng-leave.ng-leave-active,
.animate-switch.ng-enter {
opacity: 0;
}
.animate-switch.ng-leave,
.animate-switch.ng-enter.ng-enter-active {
opacity: 1;
}
이것은 체인은 아니지만 Angular의 ngAnimate 모듈을 사용하여 직접 작업하는 애니메이션입니다.또한 Angular의 웹사이트에 그 예가 있습니다.
하시면 됩니다..animation자바스크립트를 들어, 「」, 「」의 .addClass ★★★★★★★★★★★★★★★★★」removeClass
app.animation('.fade', [function() {
return {
addClass: function(element, className, doneFn) {
},
removeClass: function(element, className, doneFn) {
}
};
}]);
는 다음 중 하나의 메서드에서 요소에서 클래스를 추가 또는 삭제하고 있음을 검출하면 Angular에 의해 호출됩니다.
{{ }}를 들어 예를 들면, ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.<span class="{{shouldFade ? 'fade' : ''}}">....- 「」를 사용합니다.
ng-class예컨대<span ng-class="{fade: shouldFade}">... - 「 」의
$animate명령어로 서비스를 제공합니다.예.$animate.addClass(element, 'fade')★★★★★★★★★★★★★★★★★」$animate.removeClass(element, 'fade')
className이 뭐죠?페이드인/페이드아웃하면서 신청하는 클래스인가요?내가 기대하는 수업이요?
이 예에서는 다음과 같이 됩니다.fade이 예에서는 이미 이것이 관련된 클래스 이름임이 분명하기 때문에 조금 이상합니다.클래스를 는, 그 이 .
doneFn은 무엇을 의미합니까?애니메이션이 완성되면 실행되는 기능인가?뭐가 들어가는데?
Javascript 애니메이션을 정의한 후 호출하는 기능입니다.예를 들어, 아무것도 하지 않는 애니메이션을 모두 정의하려면:
addClass: function(element, className, doneFn) {
doneFn();
},
전화를 걸면 Angular에게 애니메이션이 완료되었음을 알립니다. 하면 것은 the, the the른 the the the the가 ng-animate래스입입니니다
이미 doneFn이 있는 경우 addClass 및 removeClass 함수는 어떻게 해야 합니까?
타임아웃이나 서드파티 라이브러리를 사용하여 요소를 변경하는 등의 코드를 입력합니다.하세요.doneFn「1」 「1」:
addClass: function(element, className, doneFn) {
element.css('opacity', 0.5);
setTimeout(function() {
doneFn();
}, 1000);
},
Angular의 ngAnimate 모듈을 사용하여 CSS 또는 JS에서 직접 작업 애니메이션을 생성하고 싶습니다.
이것은 위의 답변과는 큰 관계가 없습니다!제가 실제 사례를 하고 있다면, 적어도 제가 생각할 수 있는 다른 것은 너무 복잡하기 때문에 요소를 절대적으로 배치하지 않을까 하는 생각이 강하게 듭니다.
실제로 하여 애니메이션을 으로 ngAnimate를 하는 것이 .$animate.addClass ★★★★★★★★★★★★★★★★★」$animate.removeClass완료 시 약속을 반환합니다.요소를 숨길 때 반환되는 약속의 끝에 체인을 연결하려면 중앙 위치에서 호출하여 어떤 요소가 보이고, 숨겨지고, 표시되는지 추적해야 합니다.
이 방법은 2개의 커스텀 디렉티브를 사용하는 것입니다.숨김을 하게 , '보여주다'처럼 사용될 수 있습니다.ngShow 명령어는 할 수 , 이 는 의 체인을 합니다.ng-hide 관련 를의 클래스(및 관련 애니메이션)ng-hide서로 , 할 수 있습니다 을 사용하다ngShowUnique ★★★★★★★★★★★★★★★★★」ngShowUniqueController예를 들어 다음과 같습니다.
<div ng-show-unique-controller>
<h1 class="fade" ng-repeat="child in parent.children" ng-show-unique="parent.activeChild == child">@{{child.title}}</h1>
</div>
다음과 같이 구현할 수 있습니다.
app.directive('ngShowUniqueController', function($q, $animate) {
return {
controller: function($scope, $element) {
var elements = [];
var expressions = [];
var watchers = [];
var unregisterWatchers = null;
var visibleElement = null;
function registerWatchers() {
unregisterWatchers = $scope.$watchGroup(expressions, function(vals) {
var newCurrentIndex = vals.indexOf(true);
var addPromise;
if (visibleElement) {
// Set a fixed height, as there is a brief interval between
// removal of this class and addition of another
$element.css('height', $element[0].getBoundingClientRect().height + 'px');
addPromise = $animate.addClass(visibleElement, 'ng-hide');
} else {
addPromise = $q.when();
}
visibleElement = elements[newCurrentIndex] || null;
if (!visibleElement) return;
addPromise.then(function() {
if (visibleElement) {
$animate.removeClass(visibleElement, 'ng-hide').then(function() {
$element.css('height', '');
});
}
})
});
}
this.register = function(element, expression) {
if (unregisterWatchers) unregisterWatchers();
elements.push(element[0]);
expressions.push(expression);
registerWatchers();
// Hide elements initially
$animate.addClass(element, 'ng-hide');
};
this.unregister = function(element) {
if (unregisterWatchers) unregisterWatchers();
var index = elements.indexOf(element[0]);
if (index > -1) {
elements.splice(index, 1);
expressions.splice(index, 1);
}
registerWatchers();
};
}
};
});
app.directive('ngShowUnique', function($animate) {
return {
require: '^ngShowUniqueController',
link: function(scope, element, attrs, ngShowUniqueController) {
ngShowUniqueController.register(element, function() {
return scope.$eval(attrs.ngShowUnique);
});
scope.$on('$destroy', function() {
ngShowUniqueController.unregister(element);
});
}
};
});
이것은, http://plnkr.co/edit/1eJUou4UaH6bnAN0nJn7?p=preview 에서 확인할 수 있습니다.솔직히 말해서 이건 좀 허튼소리야.
한 번에 하나의 요소만 보여주는 ngRepeat을 사용하는 것은 좋지 않은 생각이라고 생각합니다.하나의 요소만 표시되므로 parent.activeChild 속성을 직접 사용할 수 있습니다.
다음 내용을 확인하십시오.
주의: 이 스니펫을 10분 만에 작성했습니다.최적화되지 않아 버그가 발생할 수 있습니다.스타터로 사용할 수 있습니다. : )
(function(window, angular, APP) {
APP
.value('menuObject', {
name: 'Main Navigation',
current: null,
children: [{
label: 'Don\'t ng-show element until ng-hide CSS transition is complete?',
url: 'http://stackoverflow.com/questions/33336249/dont-ng-show-element-until-ng-hide-css-transition-is-complete',
isCurrent: false
},
{
label: 'Hitmands - Linkedin',
url: 'http://it.linkedin.com/in/giuseppemandato',
isCurrent: false
},
{
label: 'Hitmands - Github',
url: 'https://github.com/hitmands',
isCurrent: false
},
{
label: 'Hitmands - StackOverflow',
url: 'http://stackoverflow.com/users/4099454/hitmands',
isCurrent: false
}
]})
.directive('menu', function(menuObject, $q) {
function menuCtrl($scope, $element) {
$scope.parent = menuObject;
this.getCurrentChild = function() {
return $scope.parent.current;
};
this.getDomContext = function() {
return $element;
};
this.setCurrentChild = function(child) {
return $q.when($scope.parent)
.then(function(parent) {
parent.current = child;
return parent;
})
.then(function(parent) {
return parent.children.forEach(function(item) {
item.isCurrent = child && (item.label === child.label);
});
})
};
}
return {
restrict: 'A',
templateUrl: 'embedded-menutemplate',
scope: {},
controller: menuCtrl
};
})
.directive('menuItem', function($animate, $q, $timeout) {
function menuItemPostLink(iScope, iElement, iAttributes, menuCtrl) {
iElement.bind('click', setCurrentTitle);
iScope.$on('$destroy', function() {
iElement.unbind('click', setCurrentTitle);
})
function setCurrentTitle(event) {
event.preventDefault();
var title;
return $q
.when(menuCtrl.getDomContext())
.then(function(_menuElement) {
title = angular.element(
_menuElement[0].querySelector('#menuItemCurrent')
);
})
.then(function() {
return title.addClass('fade-out');
})
.then(function() {
return $timeout(menuCtrl.setCurrentChild, 700, true, iScope.child);
})
.then(function() {
return title.removeClass('fade-out');
})
}
}
return {
require: '^menu',
link: menuItemPostLink,
restrict: 'A'
};
})
;
})(window, window.angular, window.angular.module('AngularAnimationExample', ['ngAnimate']));
nav {
text-align: center;
}
.link {
display: inline-block;
background-color: lightseagreen;
color: black;
padding: 5px 15px;
margin: 1em;
}
#menuItemCurrent {
padding: 1em;
text-transform: uppercase;
border: 1px solid black;
}
#menuItemCurrent span {
transition: 500ms opacity linear;
opacity: 1;
}
#menuItemCurrent.fade-out span {
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-animate.js"></script>
<article ng-app="AngularAnimationExample">
<nav menu></nav>
<script id="embedded-menutemplate" type="text/ng-template">
<nav >
<a menu-item class="link" ng-repeat="child in parent.children track by $index" ng-bind="child.label" ng-href="{{ child.url }}"></a>
<h1 id="menuItemCurrent"><span ng-bind="parent.current.url || 'NoMenuCurrentSelected'"></span></h1>
{{ parent.current || json }}
</nav>
</script>
</article>
문제는 H1이 부모 내에 위치한 블록레벨 요소이기 때문에 오버랩이 허용되지 않는다는 것입니다.그래서 하나의 애니메이션이 나타나고 있는 애니메이션을 아래로 밀어내리는 것을 볼 수 있습니다.
여기서 더 명확하게 확인할 수 있습니다: 데모
이 문제를 해결하려면 블록 수준 요소 H1을 유지하고 해당 위치를 상대적으로 설정하여 페이지 전체 흐름에서 상대적인 위치를 유지할 수 있습니다.다음으로 자 SPAN 요소를 부모 H1에 대한 절대 위치(absolute positioning)로 설정합니다.이를 통해 모든 스판 요소가 서로 겹칠 수 있습니다.
CSS
.fade {
opacity: 1;
position: relative;
}
.fade.ng-hide-add {
transition:opacity 1s ease;
position: absolute;
}
.fade.ng-hide-remove {
transition:opacity 1s ease 1s;
position: absolute;
}
.fade.ng-hide-add {
opacity:1;
}
.fade.ng-hide-add.ng-hide-add-active {
opacity:0;
}
.fade.ng-hide-remove {
opacity:0;
}
.fade.ng-hide-remove.ng-hide-remove-active {
opacity:1;
}
HTML
<body ng-controller="MainCtrl">
<h1><span class="fade" ng-repeat="child in parent.children" ng-show="parent.activeChild == child ">@{{child.title}}</span></h1>
<button ng-repeat="child in parent.children" ng-click="parent.activeChild = child">{{ child.title }}</button>
</body>
그런데 한 가지 문제가 있는데...SPAN 요소에는 절대적인 위치가 있기 때문에 애니메이션 생성 시 흐름에서 삭제되며 부모 H1은 SPAN 콘텐츠에 맞게 크기를 조정할 수 없습니다.이로 인해 SPAN이 예기치 않게 점프합니다.
이 문제를 해결하는 방법은 SPAN 리피터 뒤에 빈 공간을 추가하는 것입니다.따라서 ngRepeat SPAN이 절대적인 위치 결정으로 인해 일반 흐름에서 분리되면 ngRepeat 외부에 있는 빈 공간이 H1의 간격을 유지합니다.
여기 작동하는 플런커가 있습니다.
모든 최신 브라우저에서 지원되는 transitionend 이벤트에 대해 알아보는 것이 좋습니다.
element.addEventListener('transitionend', callback, false);
이에 대한 빠른 답변 - 이 문제를 해결하기 위해 저는 항상 콘텐츠를 절대적인 위치에 두었습니다.이렇게 하면 전환이 이루어졌을 때 동일한 위치에 유지됩니다.
은 돔의 .inline ★★★★★★★★★★★★★★★★★」inline-block가 표시됩니다.
언급URL : https://stackoverflow.com/questions/33336249/dont-ng-show-element-until-ng-hide-css-transition-is-complete
'programing' 카테고리의 다른 글
| JSON 개체의 델타 인코딩 (0) | 2023.04.04 |
|---|---|
| 상대 포지셔닝을 끄려면 어떻게 해야 합니까? (0) | 2023.04.04 |
| getJSON 동기 (0) | 2023.03.25 |
| 에 JSON 데이터를 해석하는 최선의 방법입니다.NET 객체 (0) | 2023.03.25 |
| 지시문 '...'에 필요한 컨트롤러 'ngModel'을 찾을 수 없습니다. (0) | 2023.03.25 |
