UNPKG

@thejlifex/ngx-scroll-spy

Version:

An Angular library that can spy the position of elements (inside a scrollable container) and emit the currently active (visible) element in the viewport.

89 lines 11.2 kB
import { Inject, Injectable, PLATFORM_ID } from '@angular/core'; import { ScrollSpy } from './scroll-spy'; import { isPlatformServer } from '@angular/common'; import * as i0 from "@angular/core"; /** * Scroll spy service. * * Creates a scroll-spy on the Document/Body per default and destroys it when the service is destroyed. * * Allows you to create (and destroy) scroll-spy on a scroll-container (any scrollable element). */ export class ScrollSpyService { constructor(platformId) { this.platformId = platformId; if (isPlatformServer(this.platformId)) { return; } this.defaultScrollSpy = new ScrollSpy(); this.scrollSpies = new Map(); } ngOnDestroy() { if (isPlatformServer(this.platformId)) { return; } this.defaultScrollSpy.stopSpying(); this.scrollSpies.forEach((item) => item.stopSpying()); this.scrollSpies.clear(); } /** * Create a scroll-spy for the provided `scrollContainer`. */ createScrollSpy(scrollContainerId, scrollContainer) { this.scrollSpies.set(scrollContainerId, new ScrollSpy({ scrollContainer })); } /** * Destroy the scroll-spy with ID equals the provided `scrollContainerId`. */ destroyScrollSpy(scrollContainerId) { this.scrollSpies.get(scrollContainerId)?.stopSpying(); this.scrollSpies.delete(scrollContainerId); } /** * Get the `spyTargetIsIntersecting$` observable for the provided `scrollContainerId`, * * Or the `spyTargetIsIntersecting$` of the `defaultScrollSpy` when `scrollContainerId` is `undefined`. */ getSpyTargetIsIntersecting$(scrollContainerId) { return this.getScrollSpy(scrollContainerId).spyTargetIsIntersecting$; } /** * Adds a spy-target and starts to observe that target. */ addTarget(spyTarget) { this.getScrollSpy(spyTarget.containerId).addTarget(spyTarget); } /** * Removes a spy-target and stops observing that target. */ removeTarget(spyTarget) { this.getScrollSpy(spyTarget.containerId).removeTarget(spyTarget); } /** * Get the scroll-spy for the proivded `scrollContainerId`. * * When `scrollContainerId` is `undefined` the `defaultScrollSpy` is returned. */ getScrollSpy(scrollContainerId) { if (!scrollContainerId) { return this.defaultScrollSpy; } const scrollSpy = this.scrollSpies.get(scrollContainerId); if (!scrollSpy) { throw new Error(`Unknown spyTargetContainerId: "${scrollContainerId}". Please make sure that the spyTargetContainerId inputs have the same value on the three directives: spy, spyTarget and spyTargetContainer.`); } return scrollSpy; } } ScrollSpyService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.4", ngImport: i0, type: ScrollSpyService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); ScrollSpyService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.4", ngImport: i0, type: ScrollSpyService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.4", ngImport: i0, type: ScrollSpyService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsLXNweS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNjcm9sbC1zcHkvc3JjL2xpYi9zY3JvbGwtc3B5LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQWEsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHekMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBRW5EOzs7Ozs7R0FNRztBQUlILE1BQU0sT0FBTyxnQkFBZ0I7SUFhM0IsWUFBeUMsVUFBa0I7UUFBbEIsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUN6RCxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUNyQyxPQUFPO1NBQ1I7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUN4QyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUNyQyxPQUFPO1NBQ1I7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVEOztPQUVHO0lBQ0gsZUFBZSxDQUFDLGlCQUF5QixFQUFFLGVBQXdCO1FBQ2pFLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLElBQUksU0FBUyxDQUFDLEVBQUUsZUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFFRDs7T0FFRztJQUNILGdCQUFnQixDQUFDLGlCQUF5QjtRQUN4QyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDO1FBQ3RELElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCwyQkFBMkIsQ0FBQyxpQkFBMEI7UUFDcEQsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUMsd0JBQXdCLENBQUM7SUFDdkUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsU0FBUyxDQUFDLFNBQW9CO1FBQzVCLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQ7O09BRUc7SUFDSCxZQUFZLENBQUMsU0FBb0I7UUFDL0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssWUFBWSxDQUFDLGlCQUEwQjtRQUM3QyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDdEIsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7U0FDOUI7UUFDRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDZCxNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxpQkFBaUIsOElBQThJLENBQUMsQ0FBQztTQUNwTjtRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7OzZHQWxGVSxnQkFBZ0Isa0JBYVAsV0FBVztpSEFicEIsZ0JBQWdCLGNBRmYsTUFBTTsyRkFFUCxnQkFBZ0I7a0JBSDVCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFjYyxNQUFNOzJCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE9uRGVzdHJveSwgUExBVEZPUk1fSUQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBTY3JvbGxTcHkgfSBmcm9tICcuL3Njcm9sbC1zcHknO1xyXG5pbXBvcnQgeyBTcHlUYXJnZXQgfSBmcm9tICcuL21vZGVscy9zcHktdGFyZ2V0JztcclxuaW1wb3J0IHsgU3B5VGFyZ2V0SXNJbnRlcnNlY3RpbmdFdmVudCB9IGZyb20gJy4vbW9kZWxzL3NweS10YXJnZXQtaXMtaW50ZXJzZWN0aW5nLWV2ZW50JztcclxuaW1wb3J0IHsgaXNQbGF0Zm9ybVNlcnZlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcblxyXG4vKipcclxuICogU2Nyb2xsIHNweSBzZXJ2aWNlLlxyXG4gKlxyXG4gKiBDcmVhdGVzIGEgc2Nyb2xsLXNweSBvbiB0aGUgRG9jdW1lbnQvQm9keSBwZXIgZGVmYXVsdCBhbmQgZGVzdHJveXMgaXQgd2hlbiB0aGUgc2VydmljZSBpcyBkZXN0cm95ZWQuXHJcbiAqXHJcbiAqIEFsbG93cyB5b3UgdG8gY3JlYXRlIChhbmQgZGVzdHJveSkgc2Nyb2xsLXNweSBvbiBhIHNjcm9sbC1jb250YWluZXIgKGFueSBzY3JvbGxhYmxlIGVsZW1lbnQpLlxyXG4gKi9cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgU2Nyb2xsU3B5U2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XHJcbiAgLyoqXHJcbiAgICogRGVmYXVsdCBzY3JvbGwtc3B5IG9uIHRoZSBkZWZhdWx0IHNjcm9sbCBlbGVtZW50IChEb2N1bWVudC9Cb2R5KS5cclxuICAgKi9cclxuICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRTY3JvbGxTcHkhOiBTY3JvbGxTcHk7XHJcbiAgLyoqXHJcbiAgICogTWFwIGNvbnRhaW5pbmcgY3JlYXRlZCBzY3JvbGwtc3BpZXMgKG9uIGFueSBzY3JvbGxhYmxlIGVsZW1lbnRzKS5cclxuICAgKlxyXG4gICAqIEBrZXkgc2Nyb2xsQ29udGFpbmVySWRcclxuICAgKiBAdmFsdWUgU2Nyb2xsU3B5XHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZWFkb25seSBzY3JvbGxTcGllcyE6IE1hcDxzdHJpbmcsIFNjcm9sbFNweT47XHJcblxyXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogc3RyaW5nKSB7XHJcbiAgICBpZiAoaXNQbGF0Zm9ybVNlcnZlcih0aGlzLnBsYXRmb3JtSWQpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuZGVmYXVsdFNjcm9sbFNweSA9IG5ldyBTY3JvbGxTcHkoKTtcclxuICAgIHRoaXMuc2Nyb2xsU3BpZXMgPSBuZXcgTWFwKCk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIGlmIChpc1BsYXRmb3JtU2VydmVyKHRoaXMucGxhdGZvcm1JZCkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5kZWZhdWx0U2Nyb2xsU3B5LnN0b3BTcHlpbmcoKTtcclxuICAgIHRoaXMuc2Nyb2xsU3BpZXMuZm9yRWFjaCgoaXRlbSkgPT4gaXRlbS5zdG9wU3B5aW5nKCkpO1xyXG4gICAgdGhpcy5zY3JvbGxTcGllcy5jbGVhcigpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlIGEgc2Nyb2xsLXNweSBmb3IgdGhlIHByb3ZpZGVkIGBzY3JvbGxDb250YWluZXJgLlxyXG4gICAqL1xyXG4gIGNyZWF0ZVNjcm9sbFNweShzY3JvbGxDb250YWluZXJJZDogc3RyaW5nLCBzY3JvbGxDb250YWluZXI6IEVsZW1lbnQpOiB2b2lkIHtcclxuICAgIHRoaXMuc2Nyb2xsU3BpZXMuc2V0KHNjcm9sbENvbnRhaW5lcklkLCBuZXcgU2Nyb2xsU3B5KHsgc2Nyb2xsQ29udGFpbmVyIH0pKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlc3Ryb3kgdGhlIHNjcm9sbC1zcHkgd2l0aCBJRCBlcXVhbHMgdGhlIHByb3ZpZGVkIGBzY3JvbGxDb250YWluZXJJZGAuXHJcbiAgICovXHJcbiAgZGVzdHJveVNjcm9sbFNweShzY3JvbGxDb250YWluZXJJZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICB0aGlzLnNjcm9sbFNwaWVzLmdldChzY3JvbGxDb250YWluZXJJZCk/LnN0b3BTcHlpbmcoKTtcclxuICAgIHRoaXMuc2Nyb2xsU3BpZXMuZGVsZXRlKHNjcm9sbENvbnRhaW5lcklkKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgYHNweVRhcmdldElzSW50ZXJzZWN0aW5nJGAgb2JzZXJ2YWJsZSBmb3IgdGhlIHByb3ZpZGVkIGBzY3JvbGxDb250YWluZXJJZGAsXHJcbiAgICpcclxuICAgKiBPciB0aGUgYHNweVRhcmdldElzSW50ZXJzZWN0aW5nJGAgb2YgdGhlIGBkZWZhdWx0U2Nyb2xsU3B5YCB3aGVuIGBzY3JvbGxDb250YWluZXJJZGAgaXMgYHVuZGVmaW5lZGAuXHJcbiAgICovXHJcbiAgZ2V0U3B5VGFyZ2V0SXNJbnRlcnNlY3RpbmckKHNjcm9sbENvbnRhaW5lcklkPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxTcHlUYXJnZXRJc0ludGVyc2VjdGluZ0V2ZW50PiB7XHJcbiAgICByZXR1cm4gdGhpcy5nZXRTY3JvbGxTcHkoc2Nyb2xsQ29udGFpbmVySWQpLnNweVRhcmdldElzSW50ZXJzZWN0aW5nJDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZHMgYSBzcHktdGFyZ2V0IGFuZCBzdGFydHMgdG8gb2JzZXJ2ZSB0aGF0IHRhcmdldC5cclxuICAgKi9cclxuICBhZGRUYXJnZXQoc3B5VGFyZ2V0OiBTcHlUYXJnZXQpOiB2b2lkIHtcclxuICAgIHRoaXMuZ2V0U2Nyb2xsU3B5KHNweVRhcmdldC5jb250YWluZXJJZCkuYWRkVGFyZ2V0KHNweVRhcmdldCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZW1vdmVzIGEgc3B5LXRhcmdldCBhbmQgc3RvcHMgb2JzZXJ2aW5nIHRoYXQgdGFyZ2V0LlxyXG4gICAqL1xyXG4gIHJlbW92ZVRhcmdldChzcHlUYXJnZXQ6IFNweVRhcmdldCk6IHZvaWQge1xyXG4gICAgdGhpcy5nZXRTY3JvbGxTcHkoc3B5VGFyZ2V0LmNvbnRhaW5lcklkKS5yZW1vdmVUYXJnZXQoc3B5VGFyZ2V0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgc2Nyb2xsLXNweSBmb3IgdGhlIHByb2l2ZGVkIGBzY3JvbGxDb250YWluZXJJZGAuXHJcbiAgICpcclxuICAgKiBXaGVuIGBzY3JvbGxDb250YWluZXJJZGAgaXMgYHVuZGVmaW5lZGAgdGhlIGBkZWZhdWx0U2Nyb2xsU3B5YCBpcyByZXR1cm5lZC5cclxuICAgKi9cclxuICBwcml2YXRlIGdldFNjcm9sbFNweShzY3JvbGxDb250YWluZXJJZD86IHN0cmluZyk6IFNjcm9sbFNweSB7XHJcbiAgICBpZiAoIXNjcm9sbENvbnRhaW5lcklkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRlZmF1bHRTY3JvbGxTcHk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBzY3JvbGxTcHkgPSB0aGlzLnNjcm9sbFNwaWVzLmdldChzY3JvbGxDb250YWluZXJJZCk7XHJcbiAgICBpZiAoIXNjcm9sbFNweSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gc3B5VGFyZ2V0Q29udGFpbmVySWQ6IFwiJHtzY3JvbGxDb250YWluZXJJZH1cIi4gUGxlYXNlIG1ha2Ugc3VyZSB0aGF0IHRoZSBzcHlUYXJnZXRDb250YWluZXJJZCBpbnB1dHMgaGF2ZSB0aGUgc2FtZSB2YWx1ZSBvbiB0aGUgdGhyZWUgZGlyZWN0aXZlczogc3B5LCBzcHlUYXJnZXQgYW5kIHNweVRhcmdldENvbnRhaW5lci5gKTtcclxuICAgIH1cclxuICAgIHJldHVybiBzY3JvbGxTcHk7XHJcbiAgfVxyXG59XHJcbiJdfQ==