UNPKG

ng-scroll-spy

Version:

Angular directive that tracking the scrolling of the document and highlight the navigation link

122 lines (117 loc) 4.93 kB
import * as i0 from '@angular/core'; import { Directive, Inject, HostListener, NgModule } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { extractElementPosition } from 'ng-html-util'; import { polyfill } from 'smoothscroll-polyfill'; class ScrollSpyDirective { constructor(document, el, renderer) { this.document = document; this.el = el; this.renderer = renderer; this.elements = []; this.directNavigation = false; } ngAfterContentInit() { this.collectIds(); } collectIds() { this.elements = []; let elements = this.el.nativeElement.querySelectorAll('a'); for (let i = 0; i < elements.length; i++) { let elem = elements.item(i); let id = ScrollSpyDirective.getId(elem); if (!id) continue; let destination = this._getPeerElement(id); if (!destination) continue; elem.addEventListener('click', this._onLinkClicked.bind(this)); this.elements.push({ id, link: elem, destination }); } } _onLinkClicked(event) { event.preventDefault(); let target = event.currentTarget; let id = ScrollSpyDirective.getId(target); let destination = this._getPeerElement(id); this.directNavigation = true; let position = extractElementPosition(this.document, destination); window.scrollTo({ top: position.top - 25, left: 0, behavior: 'smooth' }); this._cleanCurrentLink(); this._setCurrentLink(target); this.directNavigation = false; } _getPeerElement(id) { let destination = this.document.getElementById(id); if (!destination) return null; return destination; } static getId(elem) { let href = elem.getAttribute('href'); if (!href) return null; return href.replace('#', ''); } onWindowScroll(event) { if (this.directNavigation) return; for (let elem of this.elements) { let top = elem.destination.getBoundingClientRect().top; if (top > 0 && top < 25) { this._cleanCurrentLink(); this._setCurrentLink(elem.link); break; } } } _cleanCurrentLink() { if (!this.currentActiveLink) return; this.renderer.removeClass(this.currentActiveLink, 'active'); } _setCurrentLink(elem) { this.currentActiveLink = elem; this.renderer.addClass(this.currentActiveLink, 'active'); } } ScrollSpyDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ScrollSpyDirective, deps: [{ token: DOCUMENT }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); ScrollSpyDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.0", type: ScrollSpyDirective, selector: "[scroll-spy]", host: { listeners: { "window:scroll": "onWindowScroll($event)" } }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ScrollSpyDirective, decorators: [{ type: Directive, args: [{ selector: '[scroll-spy]' }] }], ctorParameters: function () { return [{ type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { onWindowScroll: [{ type: HostListener, args: ["window:scroll", ['$event']] }] } }); class ScrollSpyModule { constructor() { polyfill(); } } ScrollSpyModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ScrollSpyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); ScrollSpyModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ScrollSpyModule, declarations: [ScrollSpyDirective], exports: [ScrollSpyDirective] }); ScrollSpyModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ScrollSpyModule }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ScrollSpyModule, decorators: [{ type: NgModule, args: [{ declarations: [ScrollSpyDirective], exports: [ScrollSpyDirective] }] }], ctorParameters: function () { return []; } }); /** * Generated bundle index. Do not edit. */ export { ScrollSpyDirective, ScrollSpyModule }; //# sourceMappingURL=ng-scroll-spy.mjs.map