Search code examples
angularscrollangular-routing

Scrollspy effect in Angular router


I'm trying to add the Scrollspy effect to the Angular project. When a user click a link, rather than show it as a new page, that component should scroll up and the next component should come to that place. Is there a way to do it in Angular with routing? When a link get clicked, the page should animate to scrolltop as with the following jquery code

$('html, body').animate({scrollTop: offsetTop}, 'normal');

Is there any libraries or features in Angular?


Solution

  • I was looking for something very simple to handle scrolling, I ended up making my own directive :

    @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 breaks the stackblitz editor scrolling.