@q149/angular-scrollspy
Version:
A simple lightweight library for Angular which automatically updates links to indicate the currently active section in the viewport
110 lines (109 loc) • 8.97 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import { Injectable } from '@angular/core';
/**
* Service that stores a list of `Spy`'s and the state
* of their nav items `inViewport` and `active` state
*
*/
export class ScrollSpyService {
constructor() {
/**
* List of `Spy`'s
*
* \@memberof ScrollSpyService
*/
this.spys = [];
/**
* Stores requests to add items to spy when spy hasn't been created
* yet. Once spy has been added then request will be made again.
*
* \@memberof ScrollSpyService
*/
this.buffer = [];
}
/**
* Add spy to list of `spys`
*
* \@memberof ScrollSpyService
* @param {?} id
* @param {?} items
* @return {?}
*/
addSpy(id, items) {
this.spys.push({ id, items });
const /** @type {?} */ buffer = this.buffer.filter(i => i.spyId === id);
this.buffer = this.buffer.filter(i => i.spyId !== id);
buffer.forEach(i => this.setSpySectionStatus(i.sectionId, i.spyId, i.inViewport));
}
/**
* Remove spy from list of `spys`
*
* \@memberof ScrollSpyService
* @param {?} id
* @return {?}
*/
removeSpy(id) {
const /** @type {?} */ i = this.spys.findIndex(s => s.id === id);
this.spys.splice(i, 1);
}
/**
* Set the `inViewport` status for a spy item then sets the active
* to true for the first item in the list that has `inViewport`
* set to true
*
* \@memberof ScrollSpyService
* @param {?} sectionId
* @param {?} spyId
* @param {?} inViewport
* @return {?}
*/
setSpySectionStatus(sectionId, spyId, inViewport) {
const /** @type {?} */ spy = this.spys.find(s => s.id === spyId);
if (!spy) {
this.buffer.push({ sectionId, spyId, inViewport });
return;
}
const /** @type {?} */ item = spy.items.find(i => i.section === sectionId);
if (!item) {
return;
}
item.inViewport = inViewport;
const /** @type {?} */ firstInViewport = spy.items.filter(i => i.inViewport)[0];
spy.items.forEach(i => (i.active = false));
if (firstInViewport) {
firstInViewport.active = true;
firstInViewport.detectChanges();
}
}
}
ScrollSpyService.decorators = [
{ type: Injectable },
];
function ScrollSpyService_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
ScrollSpyService.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
ScrollSpyService.ctorParameters;
/**
* List of `Spy`'s
*
* \@memberof ScrollSpyService
* @type {?}
*/
ScrollSpyService.prototype.spys;
/**
* Stores requests to add items to spy when spy hasn't been created
* yet. Once spy has been added then request will be made again.
*
* \@memberof ScrollSpyService
* @type {?}
*/
ScrollSpyService.prototype.buffer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsLXNweS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQHExNDkvYW5ndWxhci1zY3JvbGxzcHkvIiwic291cmNlcyI6WyJhcHAvc2Nyb2xsLXNweS9zY3JvbGwtc3B5LXNlcnZpY2Uvc2Nyb2xsLXNweS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFhLE1BQU0sZUFBZSxDQUFDOzs7Ozs7QUFXdEQsTUFBTTs7Ozs7OztvQkFNaUIsRUFBRTs7Ozs7OztzQkFPQSxFQUFFOzs7Ozs7Ozs7O0lBTWxCLE1BQU0sQ0FBQyxFQUFVLEVBQUUsS0FBd0M7UUFDaEUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM5Qix1QkFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDakIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLENBQzdELENBQUM7Ozs7Ozs7OztJQU9HLFNBQVMsQ0FBQyxFQUFVO1FBQ3pCLHVCQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDOzs7Ozs7Ozs7Ozs7O0lBU2xCLG1CQUFtQixDQUN4QixTQUFpQixFQUNqQixLQUFhLEVBQ2IsVUFBbUI7UUFFbkIsdUJBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxLQUFLLENBQUMsQ0FBQztRQUNoRCxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDVCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUNuRCxNQUFNLENBQUM7U0FDUjtRQUNELHVCQUFNLElBQUksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUM7UUFDMUQsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ1YsTUFBTSxDQUFDO1NBQ1I7UUFFRCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3Qix1QkFBTSxlQUFlLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0QsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUUzQyxFQUFFLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1lBQ3BCLGVBQWUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBQzlCLGVBQWUsQ0FBQyxhQUFhLEVBQUUsQ0FBQztTQUNqQzs7OztZQWxFSixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgUXVlcnlMaXN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQgeyBTY3JvbGxTcHlJdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi4vc2Nyb2xsLXNweS1pdGVtL3Njcm9sbC1zcHktaXRlbS5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBTcHkgfSBmcm9tICcuLi9zaGFyZWQvc3B5Lm1vZGVsJztcclxuXHJcbi8qKlxyXG4gKiBTZXJ2aWNlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBgU3B5YCdzIGFuZCB0aGUgc3RhdGVcclxuICogb2YgdGhlaXIgbmF2IGl0ZW1zIGBpblZpZXdwb3J0YCBhbmQgYGFjdGl2ZWAgc3RhdGVcclxuICpcclxuICovXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFNjcm9sbFNweVNlcnZpY2Uge1xyXG4gIC8qKlxyXG4gICAqIExpc3Qgb2YgYFNweWAnc1xyXG4gICAqXHJcbiAgICogQG1lbWJlcm9mIFNjcm9sbFNweVNlcnZpY2VcclxuICAgKi9cclxuICBwdWJsaWMgc3B5czogU3B5W10gPSBbXTtcclxuICAvKipcclxuICAgKiBTdG9yZXMgcmVxdWVzdHMgdG8gYWRkIGl0ZW1zIHRvIHNweSB3aGVuIHNweSBoYXNuJ3QgYmVlbiBjcmVhdGVkXHJcbiAgICogeWV0LiBPbmNlIHNweSBoYXMgYmVlbiBhZGRlZCB0aGVuIHJlcXVlc3Qgd2lsbCBiZSBtYWRlIGFnYWluLlxyXG4gICAqXHJcbiAgICogQG1lbWJlcm9mIFNjcm9sbFNweVNlcnZpY2VcclxuICAgKi9cclxuICBwdWJsaWMgYnVmZmVyOiBhbnlbXSA9IFtdO1xyXG4gIC8qKlxyXG4gICAqIEFkZCBzcHkgdG8gbGlzdCBvZiBgc3B5c2BcclxuICAgKlxyXG4gICAqIEBtZW1iZXJvZiBTY3JvbGxTcHlTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHVibGljIGFkZFNweShpZDogc3RyaW5nLCBpdGVtczogUXVlcnlMaXN0PFNjcm9sbFNweUl0ZW1EaXJlY3RpdmU+KTogdm9pZCB7XHJcbiAgICB0aGlzLnNweXMucHVzaCh7IGlkLCBpdGVtcyB9KTtcclxuICAgIGNvbnN0IGJ1ZmZlciA9IHRoaXMuYnVmZmVyLmZpbHRlcihpID0+IGkuc3B5SWQgPT09IGlkKTtcclxuICAgIHRoaXMuYnVmZmVyID0gdGhpcy5idWZmZXIuZmlsdGVyKGkgPT4gaS5zcHlJZCAhPT0gaWQpO1xyXG4gICAgYnVmZmVyLmZvckVhY2goaSA9PlxyXG4gICAgICB0aGlzLnNldFNweVNlY3Rpb25TdGF0dXMoaS5zZWN0aW9uSWQsIGkuc3B5SWQsIGkuaW5WaWV3cG9ydClcclxuICAgICk7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIFJlbW92ZSBzcHkgZnJvbSBsaXN0IG9mIGBzcHlzYFxyXG4gICAqXHJcbiAgICogQG1lbWJlcm9mIFNjcm9sbFNweVNlcnZpY2VcclxuICAgKi9cclxuICBwdWJsaWMgcmVtb3ZlU3B5KGlkOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGNvbnN0IGkgPSB0aGlzLnNweXMuZmluZEluZGV4KHMgPT4gcy5pZCA9PT0gaWQpO1xyXG4gICAgdGhpcy5zcHlzLnNwbGljZShpLCAxKTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogU2V0IHRoZSBgaW5WaWV3cG9ydGAgc3RhdHVzIGZvciBhIHNweSBpdGVtIHRoZW4gc2V0cyB0aGUgYWN0aXZlXHJcbiAgICogdG8gdHJ1ZSBmb3IgdGhlIGZpcnN0IGl0ZW0gaW4gdGhlIGxpc3QgdGhhdCBoYXMgYGluVmlld3BvcnRgXHJcbiAgICogc2V0IHRvIHRydWVcclxuICAgKlxyXG4gICAqIEBtZW1iZXJvZiBTY3JvbGxTcHlTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHVibGljIHNldFNweVNlY3Rpb25TdGF0dXMoXHJcbiAgICBzZWN0aW9uSWQ6IHN0cmluZyxcclxuICAgIHNweUlkOiBzdHJpbmcsXHJcbiAgICBpblZpZXdwb3J0OiBib29sZWFuXHJcbiAgKTogdm9pZCB7XHJcbiAgICBjb25zdCBzcHkgPSB0aGlzLnNweXMuZmluZChzID0+IHMuaWQgPT09IHNweUlkKTtcclxuICAgIGlmICghc3B5KSB7XHJcbiAgICAgIHRoaXMuYnVmZmVyLnB1c2goeyBzZWN0aW9uSWQsIHNweUlkLCBpblZpZXdwb3J0IH0pO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBpdGVtID0gc3B5Lml0ZW1zLmZpbmQoaSA9PiBpLnNlY3Rpb24gPT09IHNlY3Rpb25JZCk7XHJcbiAgICBpZiAoIWl0ZW0pIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGl0ZW0uaW5WaWV3cG9ydCA9IGluVmlld3BvcnQ7XHJcbiAgICBjb25zdCBmaXJzdEluVmlld3BvcnQgPSBzcHkuaXRlbXMuZmlsdGVyKGkgPT4gaS5pblZpZXdwb3J0KVswXTtcclxuICAgIHNweS5pdGVtcy5mb3JFYWNoKGkgPT4gKGkuYWN0aXZlID0gZmFsc2UpKTtcclxuXHJcbiAgICBpZiAoZmlyc3RJblZpZXdwb3J0KSB7XHJcbiAgICAgIGZpcnN0SW5WaWV3cG9ydC5hY3RpdmUgPSB0cnVlO1xyXG4gICAgICBmaXJzdEluVmlld3BvcnQuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iXX0=