Bootstap是基於JQuery開發,Angular中不支持Bootstrap相關事件邏輯。本文基於Typecript開發了一個Angular可用的ScrollSpy控件。Scrollspy控件主要實現了左側導航以及右側正文之間的聯動和切換。因此,css
此組件主要解決兩個問題:html
(1)點擊左側導航列表,右側正文可以跟隨切換的焦點定位到具體的段落,即添加導航點擊事件git
(2)右側正文滾動時,左側導航列表能夠根據正文滾動的位置自動定位到,該段落所屬的目錄索引上。即添加正文滾動事件。github
1. 代碼結構app
1.組件代碼函數
滾動監聽指令:post
監聽滾動事件,而且獲取當前滾動焦點的元素值(element)而後切換當前導航樹位置(postion),觸發positionchange事件函數。this
//scrollspy.direct.ts import { Directive, Injectable, Input, EventEmitter, Output, ElementRef, HostListener } from '@angular/core'; @Directive({ selector: '[NgScrollSpy]' }) export class NgScrollSpyDirective { @Output() public positonChange = new EventEmitter<string>(); private currentposition: string; private Tags = ['DIV']; constructor(private _el: ElementRef) {} @HostListener('scroll', ['$event']) //監聽正文滾動事件 onScroll(event: any) { let position: 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.Tags.some(tag => tag === element.tagName)) { if ((element.offsetTop - parentOffset) <= scrollTop) { position = element.id; } } } if (position !== this.currentposition) { this.currentposition = position; this.positonChange.emit(this.currentposition); } } }
經過scrollTo(position :string)函數獲取左側導航樹點擊位置,並操做DOM定位到對應位置。spa
經過onPositionChange(position: string)函數獲取右側正文的滾動位置。code
//ngscrollspy.component.ts import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-ngscrollspy', templateUrl: './ngscrollspy.component.html', styleUrls: ['./ngscrollspy.component.css'] }) export class NgscrollspyComponent implements OnInit { constructor() { } ngOnInit() { } currentPostion = 'Phase1'; // 正文滾動事件 設置當前滾動位置,供NgScrollSpyDirective使用 onPositionChange(position: string) { this.currentPostion = position; } // 導航點擊事件 查找目錄節點別切換到節點 scrollTo(position :string) { document.querySelector('#' + position) .scrollIntoView(); } }
html
//ngscrollspy.component.html <div class="container"> <div class="row"> <div class="col-xl-6 col-lg-6 col-md-6 col-sm-6"> <h2>導航</h2> <div (click)="scrollTo('phase1')">段落1 <ng-container *ngIf="currentPostion==='phase1'">++</ng-container> </div> <div (click)="scrollTo('phase2')">段落2 <ng-container *ngIf="currentPostion==='phase2'">++</ng-container> </div> <div (click)="scrollTo('phase3')">段落3 <ng-container *ngIf="currentPostion==='phase3'">++</ng-container> </div> <div (click)="scrollTo('phase4')">段落4 <ng-container *ngIf="currentPostion==='phase4'">++</ng-container> </div> </div> <div class="col-xl-6 col-lg-6 col-md-6 col-sm-6"> <div id="phases" NgScrollSpy (positonChange)="onPositionChange($event)" style="height:150px;overflow-y: scroll;"> <div id="phase1"> <h2 style="margin:0">段落 1</h2> <PhaseText></PhaseText> </div> <div id="phase2"> <h1>段落 2</h1> <PhaseText></PhaseText> </div> <div id="phase3"> <h1>段落 3</h1> <PhaseText></PhaseText> </div> <div id="phase4"> <h1>段落 4</h1> <PhaseText></PhaseText> </div> </div> </div> </div> </div>
詳細代碼能夠訪問github倉庫