ng-animate: только добавить к dom после задержки анимации
Я пытаюсь использовать ng-animate с ng-repeat (и ng-show), чтобы удалить старое содержимое и заменить его новым.
Проблема, с которой я сталкиваюсь, заключается в том, что во время анимации remove и add как добавляемые, так и удаляемые элементы имеют display:block.
Я думал, что смогу избежать этого, используя animation-delay в CSS, но это просто задерживает затухание, а не добавление класса, который устанавливает display на элемент.
В результате получается скачкообразный переход.
Это это моя анимация CSS (вырубить):
.keyframe-fade.ng-enter,
.keyframe-fade.ng-move {
animation: 0.5s fade-in;
animation-delay: 1s;
animation-fill-mode: backwards;
}
.keyframe-fade.ng-leave {
animation: 0.5s fade-out;
}
Но это легче продемонстрировать с помощью это плунжер.
Есть идеи?
Примечание: чтобы быть ясным, желаемое поведение на плунжере связано с тем, что цветные квадраты всегда занимают одно и то же пространство, т. е. они сидят на одной линии, и кнопка не перемещается. Если возможно, я хотел бы исправить это без абсолютного позиционирования "bodges", поскольку фактическая страница, на которой я использую это, намного сложнее, чем демо подаренный.
2 ответов:
Решение, которое я нашел для этого, состоит в том, чтобы дополнить чистую CSS-анимацию очень небольшим количеством JavaScript.
Чтобы подытожить проблему:
Входящий элемент добавляется в DOM с классом
ng-enterодновременно с тем, как выходящему элементу присваивается классng-leave.Хотя есть задержка анимации, входящий элемент все еще занимает пространство
Таким образом, этот фрагмент javascript берет элемент и добавляет
ng-hideдля продолжительность отпуска-анимация, удаление ее впоследствии..animation('.keyframe-fade', ['$timeout', function ($timeout){ return { enter: function (element, done){ // Add ng-hide for the duration of the leave animation. element.addClass('ng-hide'); $timeout(function(){ element.removeClass('ng-hide'); }, 500) done(); } } }])Длительность здесь жестко закодирована, но я не вижу никакой причины, по которой вы не могли бы захватить ее из элемента вместо этого.
Улучшения / предложения приветствуются.
Вот оригинал плунькр с переменой.
Это ужасно, и для углового 2+, но просто для записи вот одна идея.
У меня есть два элемента
button, один для того, когда у пользователя есть товары в корзине, и один для того, когда их нет.Самый простой способ-это поместить
position: relativeна родительский DIV иposition: absoluteна обе кнопки. Главным недостатком является то, что родительский DIV приходится измерять вручную, и такие вещи, как центрирование, становятся сложнее.
Если намерение состоит в том, чтобы отложить добавление к DOM на основе Наблюдаемое значение, тогда я подумал: " почему бы просто не отложить наблюдаемое значение? ' который будет иметь тот же конечный эффект. Это должно быть сделано только тогда, когда переход от ложного > истинного, хотя, потому что вы только хотите скрыть его, когда он приходит в вид. Поэтому я воспользовался трубой, чтобы справиться с этим.
<!-- This button for when item is IN the cart --> <button [@cartIconAnimation] *ngIf="showCartIcon | delayTrue | async">View Cart</button> <!-- This button for when item is NOT IN the cart --> <button [@cartIconAnimation] *ngIf="showCartIcon | complement | delayTrue | async">Add to Cart</button>Это предполагает, что
showCartIconестьObservable<boolean>.Тогда трубы выглядят следующим образом, и никакой задержки не требуется по вашим критериям анимации.
@Pipe({ name: 'delayTrue' }) export class DelayTruePipe implements PipeTransform { constructor() {} transform(value: Observable<any> | any, delay: number): Observable<any> { if (isObservable(value)) { return value.pipe(distinctUntilChanged(), debounce((show) => show ? timer(delay || 500) : empty())); } else { throw Error('Needs to be an observable'); } } } @Pipe({ name: 'complement' }) export class ComplementPipe implements PipeTransform { constructor() {} transform(value: Observable<boolean> | any): Observable<any> { if (isObservable(value)) { return value.pipe(map(i => !i)); } else { throw Error('Needs to be an observable'); } } }Примечание: задержка, используемая труба должна быть больше, чем время, необходимое для исчезновения предыдущего элемента, или у вас будет та же проблема.
Канал дополнения просто инвертирует логическое значение.
Это решение работает, но оно хаки, и время может быть сложнее ошибиться, и могут быть условия гонки, поскольку два разных таймера браузера срабатывают одновременно. Я бы сделал что-то подобное, только если вы действительно не можете использовать
position: absolute.
Comments