Angular 路由器中的 Scrollspy 效果
Scrollspy effect in Angular router
我正在尝试将 Scrollspy 效果添加到 Angular 项目中。当用户单击 link,而不是将其显示为新页面时,该组件应向上滚动,下一个组件应到达该位置。有没有办法在 Angular 中使用路由来做到这一点?当 link 被点击时,页面应该像下面的 jquery 代码一样滚动到顶部
$('html, body').animate({scrollTop: offsetTop}, 'normal');
Angular 中是否有任何库或功能?
我一直在寻找处理滚动的非常简单的方法,最后我制定了自己的指令:
@Directive({
selector: '[scrollSpy]'
})
export class ScrollSpyDirective {
@Input() public spiedTags = [];
@Output() public sectionChange = new EventEmitter<string>();
private currentSection: string;
constructor(private _el: ElementRef) {}
@HostListener('scroll', ['$event'])
onScroll(event: any) {
let currentSection: string;
const children = this._el.nativeElement.children;
const scrollTop = event.target.scrollTop;
const parentOffset = event.target.offsetTop;
for (let i = 0; i < children.length; i++) {
const element = children[i];
if (this.spiedTags.some(spiedTag => spiedTag === element.tagName)) {
if (element.offsetTop - parentOffset <= scrollTop) {
currentSection = element.id;
}
}
}
if (currentSection !== this.currentSection) {
this.currentSection = currentSection;
this.sectionChange.emit(this.currentSection);
}
}
}
Here is a demo link with routing integrated. For some reason, the stackblitz edition version 中断了 stackblitz 编辑器的滚动。
这是 Angular 9 的工作版本:
import { Directive, Input, EventEmitter, Output, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[scrollSpy]'
})
export class ScrollSpyDirective {
@Input() public spiedTags = [];
@Output() public sectionChange = new EventEmitter<string>();
private currentSection: string;
constructor(private _el: ElementRef) {}
@HostListener('window:scroll', ['$event'])
onScroll(event: any) {
let currentSection: string;
const children = this._el.nativeElement.children;
const scrollTop = event.target.scrollingElement.scrollTop;
const parentOffset = event.target.scrollingElement.offsetTop;
for (let i = 0; i < children.length; i++) {
const element = children[i];
if (this.spiedTags.some(spiedTag => spiedTag === element.tagName)) {
if ((element.offsetTop - parentOffset) <= scrollTop) {
currentSection = element.id;
}
}
}
if (currentSection !== this.currentSection) {
this.currentSection = currentSection;
this.sectionChange.emit(this.currentSection);
}
}
}
我正在尝试将 Scrollspy 效果添加到 Angular 项目中。当用户单击 link,而不是将其显示为新页面时,该组件应向上滚动,下一个组件应到达该位置。有没有办法在 Angular 中使用路由来做到这一点?当 link 被点击时,页面应该像下面的 jquery 代码一样滚动到顶部
$('html, body').animate({scrollTop: offsetTop}, 'normal');
Angular 中是否有任何库或功能?
我一直在寻找处理滚动的非常简单的方法,最后我制定了自己的指令:
@Directive({
selector: '[scrollSpy]'
})
export class ScrollSpyDirective {
@Input() public spiedTags = [];
@Output() public sectionChange = new EventEmitter<string>();
private currentSection: string;
constructor(private _el: ElementRef) {}
@HostListener('scroll', ['$event'])
onScroll(event: any) {
let currentSection: string;
const children = this._el.nativeElement.children;
const scrollTop = event.target.scrollTop;
const parentOffset = event.target.offsetTop;
for (let i = 0; i < children.length; i++) {
const element = children[i];
if (this.spiedTags.some(spiedTag => spiedTag === element.tagName)) {
if (element.offsetTop - parentOffset <= scrollTop) {
currentSection = element.id;
}
}
}
if (currentSection !== this.currentSection) {
this.currentSection = currentSection;
this.sectionChange.emit(this.currentSection);
}
}
}
Here is a demo link with routing integrated. For some reason, the stackblitz edition version 中断了 stackblitz 编辑器的滚动。
这是 Angular 9 的工作版本:
import { Directive, Input, EventEmitter, Output, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[scrollSpy]'
})
export class ScrollSpyDirective {
@Input() public spiedTags = [];
@Output() public sectionChange = new EventEmitter<string>();
private currentSection: string;
constructor(private _el: ElementRef) {}
@HostListener('window:scroll', ['$event'])
onScroll(event: any) {
let currentSection: string;
const children = this._el.nativeElement.children;
const scrollTop = event.target.scrollingElement.scrollTop;
const parentOffset = event.target.scrollingElement.offsetTop;
for (let i = 0; i < children.length; i++) {
const element = children[i];
if (this.spiedTags.some(spiedTag => spiedTag === element.tagName)) {
if ((element.offsetTop - parentOffset) <= scrollTop) {
currentSection = element.id;
}
}
}
if (currentSection !== this.currentSection) {
this.currentSection = currentSection;
this.sectionChange.emit(this.currentSection);
}
}
}