Я пытаюсь использовать ng-animate
, чтобы получить поведение, подобное JQuery slideUp()
и slideDown()
. Только я предпочел бы использовать ng-show
Я смотрю здесь учебник ng-animate - http://www.yearofmoo.com/2013/04/animation-in-angularjs.html,
и я могу воспроизвести эффект fade in/out в представленном примере.
Как я могу изменить css, чтобы получить слайд вверх/вниз? Кроме того, если возможно, лучше, чтобы css не знал о высоте компонента в пикселях. Таким образом, я могу повторно использовать CSS для разных элементов.
Я написал директиву Angular, которая делает slideToggle()
без jQuery.
Это на самом деле довольно легко сделать. Все, что вам нужно сделать, это изменить css.
Здесь сценарий с очень простой анимацией затухания: http://jsfiddle.net/elthrasher/sNpjH/
Чтобы превратить его в скользящую анимацию, мне сначала пришлось поместить свой элемент в поле (это контейнер слайдов), затем я добавил еще один элемент, чтобы заменить тот, который уходил, только потому, что я думал, что он будет выглядеть красиво, Возьмите его, и пример будет работать.
Я изменил анимацию css с "fade" на "slide", но обратите внимание, что это имена, которые я им дал. Я мог бы написать слайд-анимацию css с именем "fade" или что-нибудь еще в этом отношении.
Важная часть - это то, что в css. Здесь оригинал "fade" css:
.fade-hide, .fade-show {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
}
.fade-hide {
opacity:1;
}
.fade-hide.fade-hide-active {
opacity:0;
}
.fade-show {
opacity:0;
}
.fade-show.fade-show-active {
opacity:1;
}
Этот код изменяет непрозрачность элемента от 0 (полностью прозрачный) до 1 (полностью непрозрачный) и обратно. Решение состоит в том, чтобы оставить непрозрачность в одиночку и вместо этого изменить верхнюю (или левую, если вы хотите переместить влево-вправо).
.slide-hide, .slide-show {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
}
.slide-hide {
position: relative;
top: 0;
}
.slide-hide.slide-hide-active {
position: absolute;
top: -100px;
}
.slide-show {
position: absolute;
top: 100px;
}
.slide-show.slide-show-active {
position: relative;
top: 0px;
}
Я также перехожу от относительного к абсолютному позиционированию, поэтому только один из элементов занимает место в контейнере за раз.
Здесь готовый продукт: http://jsfiddle.net/elthrasher/Uz2Dk/. Надеюсь, это поможет!
Это действительно можно сделать в CSS и очень минимальном JS, просто добавив класс CSS (не устанавливайте стили непосредственно в JS!), например. a ng-click
. Принцип состоит в том, что нельзя окутать height: 0;
в height: auto;
, но это может быть обмануто анимированием свойства max-height
. Контейнер будет расширяться до значения "auto-height", когда установлен .foo-open
- нет необходимости в фиксированной высоте или позиционировании.
.foo {
max-height: 0;
}
.foo--open {
max-height: 1000px; /* some arbitrary big value */
transition: ...
}
см. эту скрипку превосходной Ли Веро
В связи с замечанием, высказанным в комментариях, обратите внимание, что, хотя эта анимация отлично работает с линейным ослаблением, любое экспоненциальное ослабление приведет к поведению, отличному от того, что можно было ожидать - из-за того, что анимированное свойство max-height
, а не height
сам; в частности, будет отображаться только фракция height
кривой ослабления max-height
.
max-height
.
max-height
. Именно так должны работать переходы. Этот метод на самом деле имеет то преимущество, что скорость скольжения / опускания остается постоянной независимо от height
обновить для Angular 1.2 + (v1.2.6 на момент публикации):
.stuff-to-show {
position: relative;
height: 100px;
-webkit-transition: top linear 1.5s;
transition: top linear 1.5s;
top: 0;
}
.stuff-to-show.ng-hide {
top: -100px;
}
.stuff-to-show.ng-hide-add,
.stuff-to-show.ng-hide-remove {
display: block!important;
}
(plunker)
В конце концов я отказался от кода для своего другого ответа на этот вопрос и пошел с этим ответом.
Я считаю, что лучший способ сделать это - не использовать ng-show
и ng-animate
вообще.
/* Executes jQuery slideDown and slideUp based on value of toggle-slidedown
attribute. Set duration using slidedown-duration attribute. Add the
toggle-required attribute to all contained form controls which are
input, select, or textarea. Defaults to hidden (up) if not specified
in slidedown-init attribute. */
fboApp.directive('toggleSlidedown', function(){
return {
restrict: 'A',
link: function (scope, elem, attrs, ctrl) {
if ('down' == attrs.slidedownInit){
elem.css('display', '');
} else {
elem.css('display', 'none');
}
scope.$watch(attrs.toggleSlidedown, function (val) {
var duration = _.isUndefined(attrs.slidedownDuration) ? 150 : attrs.slidedownDuration;
if (val) {
elem.slideDown(duration);
} else {
elem.slideUp(duration);
}
});
}
}
});
Эта анимация javascript на основе классов работает в AngularJS 1.2 (и проверена 1.4)
Изменить. Я закончил тем, что отказался от этого кода и пошел совершенно в другом направлении. Мне нравится мой другой ответ намного лучше. Этот ответ даст вам некоторые проблемы в определенных ситуациях.
myApp.animation('.ng-show-toggle-slidedown', function(){
return {
beforeAddClass : function(element, className, done){
if (className == 'ng-hide'){
$(element).slideUp({duration: 400}, done);
} else {done();}
},
beforeRemoveClass : function(element, className, done){
if (className == 'ng-hide'){
$(element).css({display:'none'});
$(element).slideDown({duration: 400}, done);
} else {done();}
}
}
});
Просто добавьте класс .ng-hide-toggle-slidedown
к элементу контейнера, а поведение слайда jQuery будет реализовано на основе класса ng-hide.
Вы должны указать строку $(element).css({display:'none'})
в методе beforeRemoveClass
, потому что jQuery не будет выполнять slownDown, если элемент не находится в состоянии display: none
до запуска анимации jQuery. AngularJS использует CSS
.ng-hide:not(.ng-hide-animate) {
display: none !important;
}
чтобы скрыть элемент. jQuery не знает об этом состоянии, а jQuery будет нуждаться в display:none
до первой анимации спуска вниз.
Анимация AngularJS добавит классы .ng-hide-animate
и .ng-animate
во время анимации.
Вы должны использовать анимацию Javascript для этого - это невозможно в чистом CSS, потому что вы не можете знать высоту любого элемента. Следуйте инструкциям, которые у вас есть о реализации анимации javascript, и скопируйте slideUp и slideDown из источника jQuery.
Что случилось с использованием ng-animate
для ng-show
, как вы упомянули?
<script src="lib/angulr.js"></script>
<script src="lib/angulr_animate.js"></script>
<script>
var app=angular.module('ang_app', ['ngAnimate']);
app.controller('ang_control01_main', function($scope) {
});
</script>
<style>
#myDiv {
transition: .5s;
background-color: lightblue;
height: 100px;
}
#myDiv.ng-hide {
height: 0;
}
</style>
<body ng-app="ang_app" ng-controller="ang_control01_main">
<input type="checkbox" ng-model="myCheck">
<div id="myDiv" ng-show="myCheck"></div>
</body>