在我的 Angular 应用程序(当前为 Angular 11)中,我总是使用一个返回顶部按钮,该按钮会在用户滚动时出现。单击该按钮后,该按钮会将窗口滚动回顶部,然后消失。经典行为。
但现在我更改了布局,并用 Angular Material Tabs 替换了引导导航栏。
我的 BodyComponent 现在看起来像这样:
<div id="body.component.container" style="margin-top: 62px;">
<mat-tab-group [(selectedIndex)]="selectedMatTabIndex">
<mat-tab>
<ng-template matTabLabel>
<span style="font-family: 'Arial Narrow', monospace; font-size: 16px; font-weight: bold;">Tab1</span>
</ng-template>
<app-content-component-001></app-content-component-001>
</mat-tab>
<mat-tab>
<ng-template matTabLabel>
<span style="font-family: 'Arial Narrow', monospace; font-size: 16px; font-weight: bold;">Tab2</span>
</ng-template>
<app-content-component-002></app-content-component-002>
</mat-tab>
</mat-tab-group>
</div>
<app-back-to-top
[acceleration]="1000"
[animate]="true"
[scrollDistance]="50"
[speed]="5000">
</app-back-to-top>
我面临的问题是,不再有可捕获的常见滚动事件。通常,正如大家肯定知道的那样,在返回顶部按钮组件内,我们会监听 HostEvent window:scroll
但这在 MatTabs 内不起作用。
@HostListener('window:scroll', [])
onWindowScroll() {
if (this.isBrowser()) {
this.animationState = this.getCurrentScrollTop() > this.scrollDistance / 2 ? 'in' : 'out';
}
}
我把这个返回顶部按钮组件放在哪里并不重要。我尝试将其直接放入 body 组件(多年来一直如此)、container-div、MatTabGroup 和每个 MatTab 中。 window:scroll
事件未显示。
在通过互联网进行(重新)搜索时,我发现了一些微弱的提示,表明我必须使用 CDK 的一些指令,但没有示例如何使用。
所以我有问题。
- 如何检测 Material Tab 中的 scoll 事件以使返回顶部按钮再次淡入?
- 如何以编程方式在“ Material ”选项卡内滚动回顶部?
最佳答案
我自己找到了解决方案。这实际上是我在发帖之前尝试采用的方式。我必须使用 cdkScrollable 指令。
现在我知道怎么做了。您必须在每个 MatTab 内显示的组件周围放置一个 div。然后您必须将 cdkScrollable 指令附加到这些 div。然后您可以使用 TS 代码中的 ScrollDispatcher 捕获滚动事件。
最后看起来像这样:
我的BodyComponent的HTML
<div id="body.component.container" style="margin-top: 62px;">
<mat-tab-group [(selectedIndex)]="selectedMatTabIndex">
<mat-tab>
<ng-template matTabLabel>
<span style="font-family: 'Arial Narrow', monospace; font-size: 16px; font-weight: bold;">Tab1</span>
</ng-template>
<div cdkScrollable>
<app-content-component-001></app-content-component-001>
</div>
</mat-tab>
<mat-tab>
<ng-template matTabLabel>
<span style="font-family: 'Arial Narrow', monospace; font-size: 16px; font-weight: bold;">Tab2</span>
</ng-template>
<div cdkScrollable>
<app-content-component-002></app-content-component-002>
</div>
</mat-tab>
</mat-tab-group>
</div>
<app-back-to-top
[scrollingNativeElement]="scrollingNativeElement">
</app-back-to-top>
我的BodyComponent的TS(仅重要的代码行)
import { CdkScrollable, ScrollDispatcher } from '@angular/cdk/overlay';
scrollingNativeElement: HTMLElement;
constructor(public scrollDispatcher: ScrollDispatcher){}
ngOnInit(): void {
this.scrollDispatcher.scrolled().subscribe((data: CdkScrollable) => {
this.scrollingNativeElement = data.getElementRef().nativeElement;
});
}
我的BackToTopButtonComponent的TS
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
@Component({
selector: 'app-back-to-top',
templateUrl: './back-to-top.component.html',
styleUrls: ['./back-to-top.component.css'],
animations: [
trigger('appearInOut', [
state('in', style({
'display': 'block',
'opacity': '1'
})),
state('out', style({
'display': 'none',
'opacity': '0'
})),
transition('in => out', animate('400ms ease-in-out')),
transition('out => in', animate('400ms ease-in-out'))
]),
]
})
export class BackToTopComponent implements OnInit, OnDestroy, OnChanges {
animationState = 'out';
@Input() scrollingNativeElement: HTMLElement;
ngOnInit(): void
{
}
ngOnDestroy(): void
{
}
ngOnChanges(changes: SimpleChanges): void
{
if (changes['scrollingNativeElement'].currentValue)
{
this.animationState = (this.scrollingNativeElement.scrollTop > 0) ? 'in' : 'out';
}
}
scrollToTop(): void
{
this.scrollingNativeElement.scrollTo(0, 0);
}
}
我的BackToTopButtonComponent的HTML
<button mat-fab type="button"
id="BT1000"
aria-label="Back to top of the page"
class="back-to-top-button"
[@appearInOut]="animationState"
(click)="scrollToTop()"
matTooltip="scroll to top">
<mat-icon class="back-to-top-mat-icon" svgIcon="YOUR ICON GOES HERE"></mat-icon>
</button>
我的BackToTopButtonComponent的CSS
.back-to-top-button {
position: fixed;
right: 40px;
bottom: 40px;
border: 0;
outline: none;
color: black;
background: #f2f2f2;
text-decoration: none;
cursor: pointer;
z-index: 9999;
}
.back-to-top-mat-icon {
transform: scale(1.5);
}
关于angular - 如何检测 Angular Material 选项卡内的滚动事件以及如何以编程方式滚动回顶部?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66269273/