Angular 2向上和向下滑动动画

时间:2016-06-15 20:07:14

标签: angular typescript angular2-template angular2-directives

我最近构建了以下Angular 2 Read More组件。这个组件的作用是使用"折叠和扩展长文本块;阅读更多"和#34;阅读更少"链接。不是基于字符数,而是基于指定的最大高度。

import { Component, Input, ElementRef, AfterViewInit } from '@angular/core';

@Component({
    selector: 'read-more',
    template: `
        <div [innerHTML]="text" [class.collapsed]="isCollapsed" [style.height]="isCollapsed ? maxHeight+'px' : 'auto'">
        </div>
            <a *ngIf="isCollapsable" (click)="isCollapsed =! isCollapsed">Read {{isCollapsed? 'more':'less'}}</a>
    `,
    styles: [`
        div.collapsed {
            overflow: hidden;
        }
    `]
})
export class ReadMoreComponent implements AfterViewInit {

    //the text that need to be put in the container
    @Input() text: string;

    //maximum height of the container
    @Input() maxHeight: number = 100;

    //set these to false to get the height of the expended container 
    public isCollapsed: boolean = false;
    public isCollapsable: boolean = false;

    constructor(private elementRef: ElementRef) {
    }

    ngAfterViewInit() {
        let currentHeight = this.elementRef.nativeElement.getElementsByTagName('div')[0].offsetHeight;
       //collapsable only if the contents make container exceed the max height
        if (currentHeight > this.maxHeight) {
            this.isCollapsed = true;
            this.isCollapsable = true;
        }
    }
}

并使用如下:

<read-more [text]="details" [maxHeight]="250"></read-more>

该组件运作良好。现在我需要向组件添加一些向上/向下滑动动画,以便在单击“阅读更多”链接时向下滑动,当单击“阅读更少”时,内容会向上滑动到指定的最大高度。

有人可以指导如何实现这个目标吗?

4 个答案:

答案 0 :(得分:13)

  

自动属性计算

     

具有自动高度计算的动画

     

有时您不知道维度样式属性的值   直到运行时例如,元素通常具有宽度和高度   这取决于他们的内容和屏幕尺寸。这些属性是   使用CSS制作动画通常很棘手。

     

在这些情况下,您可以使用特殊的*属性值   属性的值在运行时计算,然后插入到   动画。

     

在此示例中,离开动画采用元素的任何高度   在它离开之前有动画从那个高度到零:

animations: [
  trigger('shrinkOut', [
    state('in', style({height: '*'})),
    transition('* => void', [
      style({height: '*'}),
      animate(250, style({height: 0}))
    ])
  ])
]

来自Angular官方文档:https://angular.io/guide/animations#automatic-property-calculation

答案 1 :(得分:12)

我的解决方案包含sendevent-F jobs_on_ice :enter:leave

*ngIf

模板:

@Component({
    selector: 'accordion',
    templateUrl: './accordion.component.html',
    animations: [
        trigger('slideInOut', [
            state('in', style({height: '*', opacity: 0})),
            transition(':leave', [
                style({height: '*', opacity: 1}),

                group([
                    animate(300, style({height: 0})),
                    animate('200ms ease-in-out', style({'opacity': '0'}))
                ])

            ]),
            transition(':enter', [
                style({height: '0', opacity: 0}),

                group([
                    animate(300, style({height: '*'})),
                    animate('400ms ease-in-out', style({'opacity': '1'}))
                ])

            ])
        ])
    ]
})
...

不幸的是我还必须加入此修复程序(对于slideOut): https://github.com/angular/angular/issues/15798

答案 2 :(得分:2)

Threeve的回答是正确的 - 唯一的问题是CSS过渡不适用于'auto'。因此,您需要在ngAfterViewInit函数中捕获自动高度并将其存储为字符串。另请注意,使用setTimeout函数可以停止可能发生的“单向数据流违规错误”。

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #282828;
  max-width: 100%;
  width: 100%;
  box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}

答案 3 :(得分:1)

这是我在Angular 8.1.2中使用的。该代码的优点在于它支持需要显示/折叠的div高度不受限制,并且可以平滑过渡。

TS文件:

import {Component, OnInit} from '@angular/core';
import {trigger, transition, animate, style, state} from '@angular/animations';

@Component({
    selector: 'app-all-data',
    templateUrl: './all-data.page.html',
    styleUrls: ['./all-data.page.scss'],
    animations: [
        trigger('openClose', [
            state('open', style({
                height: '*',
                opacity: 1,
            })),
            state('closed', style({
                height: '0',
                opacity: 0
            })),
            transition('open => closed', [
                animate('0.35s')
            ]),
            transition('closed => open', [
                animate('0.35s')
            ]),
        ]),
    ]
})
export class AllDataPage implements OnInit {

    showCardBody = false;

    constructor() {
    }

    ngOnInit() {
    }

    /**
     * Toggle details on click
     */
    showDetails() {
        this.showCardBody = !this.showCardBody;
    }

}

HTML文件:

<button type="button" (click)="showDetails()">
       Toggle Details
</button>

<div class="card-body" [@openClose]="showCardBody ? 'open' : 'closed'">
       <p>This is some content</p>
       <p>This is some content</p>
       <p>This is some content</p>       
       <p>This is some content</p>
       <p>This is some content</p>
</div>