Angular 角度2上下滑动动画
我最近构建了以下Angular 2 Read More组件。该组件所做的是使用“多读”和“少读”链接折叠和扩展长文本块。不是基于字符数,而是基于指定的最大高度Angular 角度2上下滑动动画,angular,typescript,angular2-template,angular2-directives,Angular,Typescript,Angular2 Template,Angular2 Directives,我最近构建了以下Angular 2 Read More组件。该组件所做的是使用“多读”和“少读”链接折叠和扩展长文本块。不是基于字符数,而是基于指定的最大高度 import { Component, Input, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'read-more', template: ` <div [innerHTML]="text" [
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;
}
}
}
从'@angular/core'导入{Component,Input,ElementRef,AfterViewInit};
@组成部分({
选择器:“阅读更多”,
模板:`
阅读{{isCollapsed?'more':'less'}
`,
风格:[`
部门崩溃{
溢出:隐藏;
}
`]
})
导出类ReadMoreComponent在ViewInit之后实现{
//需要放入容器中的文本
@Input()文本:字符串;
//容器的最大高度
@输入()最大高度:数字=100;
//将这些值设置为false以获取扩展容器的高度
public iscollected:boolean=false;
public isCollapsable:boolean=false;
构造函数(私有elementRef:elementRef){
}
ngAfterViewInit(){
让currentHeight=this.elementRef.nativeElement.getElementsByTagName('div')[0].offsetHeight;
//仅当容器中的内容物超过最大高度时才可折叠
如果(currentHeight>this.maxHeight){
this.isCollapsed=true;
this.isCollapsable=true;
}
}
}
用起来像:
<read-more [text]="details" [maxHeight]="250"></read-more>
该组件运行良好。现在,我需要向组件添加一些向上/向下滑动动画,以便在单击“读取更多”链接时内容向下滑动,在单击“读取更少”时,内容向上滑动到指定的最大高度
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;
}
}
}
任何人都可以指导如何实现这一点吗?Threeve的答案是正确的-唯一的问题是CSS转换不能与“自动”一起工作。因此,需要在ngAfterViewInit函数中捕获自动高度,并将其存储为字符串。还请注意使用setTimeout函数来停止可能发生的“单向数据流冲突错误”
import { Component, Input, ElementRef, AfterViewInit } from '@angular/core';
@Component({
selector: 'read-more',
template: `
<div [style.height]="isCollapsed ? maxHeight+'px' : autoHeight">
<ng-content></ng-content>
</div>
<span *ngIf="isCollapsable" class="btn-link cpointer" (click)="isCollapsed =! isCollapsed">Read {{isCollapsed? 'more':'less'}} ...</span>
`,
styles: [` div { overflow-y: hidden;
-moz-transition: height .5s;
-ms-transition: height .5s;
-o-transition: height .5s;
-webkit-transition: height .5s;
transition: height .5s; ease;}
.cpointer {cursor:pointer; }
`]
})
export class ReadMoreComponent implements AfterViewInit {
@Input()
maxHeight: number = 40; //two lines
////set these to false to get the height of the expended container
isCollapsed: boolean = false;
isCollapsable: boolean = false;
autoHeight: string= "auto";
constructor(private elementRef: ElementRef) {}
ngAfterViewInit() {
// Inportant !!
// wait a tick to avoid one-time devMode
// unidirectional-data-flow-violation error
setTimeout(_ => {
let currentHeight = this.elementRef.nativeElement.getElementsByTagName('div')[0].offsetHeight;
this.autoHeight = currentHeight + "px";
//collapsable only if the contents make container exceed the max height
if (currentHeight >= this.maxHeight) {
this.isCollapsed = true;
this.isCollapsable = true;
}
}
);
}
}
从'@angular/core'导入{Component,Input,ElementRef,AfterViewInit};
@组成部分({
选择器:“阅读更多”,
模板:`
阅读{{isCollapsed?'more':'less'}。。。
`,
样式:[`div{overflow-y:hidden;
-moz过渡:高度0.5s;
-ms转换:高度0.5s;
-o型过渡:高度5s;
-webkit过渡:高度0.5s;
转换:高度.5s;轻松;}
.cpointer{cursor:pointer;}
`]
})
导出类ReadMoreComponent在ViewInit之后实现{
@输入()
maxHeight:number=40;//两行
////将这些值设置为false以获取扩展容器的高度
isCollapsed:boolean=false;
isCollapsable:boolean=false;
自动高度:string=“auto”;
构造函数(私有elementRef:elementRef){}
ngAfterViewInit(){
//重要的!!
//等待勾号以避免使用一次性devMode
//单向数据流冲突错误
setTimeout(U8;=>{
让currentHeight=this.elementRef.nativeElement.getElementsByTagName('div')[0].offsetHeight;
this.autoHeight=当前高度+“px”;
//仅当容器中的内容物超过最大高度时才可折叠
如果(currentHeight>=此.maxHeight){
this.isCollapsed=true;
this.isCollapsable=true;
}
}
);
}
}
自动属性计算
具有自动高度计算的动画
有时您不知道标注样式特性的值
直到运行时。例如,元素通常具有宽度和高度
这取决于他们的内容和屏幕大小。这些属性是
通常很难用CSS设置动画
在这些情况下,可以使用特殊的*属性值,以便
属性的值在运行时计算,然后插入
动画
在本例中,左动画采用元素的任何高度
在它离开之前有,并从该高度设置动画到零:
animations: [
trigger('shrinkOut', [
state('in', style({height: '*'})),
transition('* => void', [
style({height: '*'}),
animate(250, style({height: 0}))
])
])
]
来自Angular官方文档(现在作为存档):使用
的我的解决方案:输入,:离开和*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'}))
])
])
])
]
})
...
模板:
<div *ngIf="shown" [@slideInOut] >
// ...content
</div>
//…内容
不幸的是,我还必须合并此修复程序(用于滑出):
这是我在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;
}
}
<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>
HTML文件:
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;
}
}
<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>
切换细节
这是一些内容
这是一些内容
这是一些内容
这是一些内容
这是一些内容
。这个例子正是你想要做的。谢谢你,第五,我实际上试着将下面的样式信息添加到我上面的组件中,但这似乎不起作用。样式:[`div.collazed{overflow:hidden;},
div{transition:height 500ms ease;}`]如果适合您,你能证明我的解决方案有效吗?解决方案似乎只有一种方式-向上滑动。尝试过这种方法,但元素内的文本没有动画,但当我为容器添加一些背景色时,它以某种方式起作用,请告诉我为什么?此解决方案是否仅向上滑动(折叠/隐藏)?而不是向下(展开/显示)?伟大的解决方案伙伴,这正是我所寻找的:)正是我所寻找的。简直太棒了。。。!我会使用(单击)=“toggleDetails()”而不是showDetails(),如果没有*ngIf,这很好