一些说明可以参考Angular获取DOM元素_EchoDSun的博客-优快云博客
写法参考:js实现html页面滚动条向下拉到一定的程度时,某个div就固定在顶部,向上拉时返回原位置。_毅个混蛋的专栏-优快云博客_页面滚动时某个div固定
组件本来是随着页面一起上划的,到了页面顶端以后,组件固定的页面顶端,示例代码:
html:
<div class="home-page">
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
<!-- 固定的card -->
<mat-card #fixedCard [ngClass]="fixCard()">固定的card</mat-card>
<!-- 固定的card -->
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
<mat-card>card 1</mat-card>
<mat-card>card 1</mat-card>
<mat-card>card 1</mat-card>
</div>
TS:
import { AfterViewInit, Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
import { fromEvent } from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit, AfterViewInit {
@ViewChild('fixedCard', { read: ElementRef })
fixedCard!: ElementRef;
subscribeScoll: any;
// 当前位置距离最顶端的距离--监听的是page的移动
pageTop: number = 0;
elementTop: number = 0;
originalElementTop: number = 0;
constructor() { }
ngOnInit(): void {
}
ngAfterViewInit(): void {
// 在渲染完成以后,监听页面滚动
this.subscribeScoll = fromEvent(window, 'scroll')
.subscribe((event) => {
this.onWindowScroll();//调用
});
}
onWindowScroll() {
this.pageTop = this.scollPostion().top;
this.elementTop = this.getElementViewTop(this.fixedCard);
}
// 监听网页滚动
scollPostion() {
var top = 0;
var left = 0;
var width = 0;
var height = 0;
if (document.documentElement && document.documentElement.scrollTop) {
top = document.documentElement.scrollTop;
left = document.documentElement.scrollLeft;
width = document.documentElement.scrollWidth;
height = document.documentElement.scrollHeight;
} else if (document.body) {
top = document.body.scrollTop;
left = document.body.scrollLeft;
width = document.body.scrollWidth;
height = document.body.scrollHeight;
}
return {
top: top,
left: left,
width: width,
height: height
};
}
// 获取组件距离顶部的距离
getElementViewTop(element: any) {
var elementTop = element.nativeElement.offsetTop;
return elementTop;
}
fixCard() {
var result = '';
if (this.elementTop != 0 && this.elementTop - this.pageTop <= 10) {
// 当设置top的时候,会修改组件的位置
result = 'fixed';
} else {
// 记录原始的位置,刚开始初始化的时候,距离为0,滚动以后改为初始位置
// 因此记录下初始位置,以便后续复原
if (this.elementTop != 0) {
this.originalElementTop = this.elementTop;
}
result = '';
}
if (this.pageTop < this.originalElementTop-100) {
result = '';
}
return result;
}
}
css样式:
.home-page {
background-color: #e9e9e9;
}
.fixed {
width: 100%;
position: fixed;
top:10px;
left:0;
z-index: 2;
}
.float {
background-color: aqua;
}
.example-card {
max-width: 400px;
// background-color: white;
}
.example-header-image {
background-image: url('https://material.angular.io/assets/img/examples/shiba1.jpg');
background-size: cover;
}
还有另外一种写法,核心的内容还是比较页面上划的距离和元素上划的距离,处理方法上换成了使用Renderer2 的 addClass() 方法来设定元素的样式,写起来更加简便。
参考:
只要修改Ts文件即可:Angular2-6 实现吸顶效果指令_可乐会唱歌的博客-优快云博客
import { AfterViewInit, Component, ElementRef, HostListener, OnInit, Renderer2, ViewChild } from '@angular/core';
import { fromEvent } from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit, AfterViewInit {
// 元素距离顶部的原始距离
toTop: number = 0;
// 吸顶元素
@ViewChild('fixedCard', { read: ElementRef })
toTopElement: any;
constructor(private renderer2: Renderer2) {
}
ngAfterViewInit(): void {
this.toTop = this.toTopElement.nativeElement.offsetTop;
fromEvent(window, 'scroll').subscribe((event) => {
if (document.documentElement.scrollTop >= this.toTop) {
this.renderer2.addClass(this.toTopElement.nativeElement, 'fixed');
} else {
this.renderer2.removeClass(this.toTopElement.nativeElement, 'fixed');
}
});
}
ngOnInit(): void {
}
}