igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
93 lines (84 loc) • 2.74 kB
text/typescript
import { NgZone } from '@angular/core';
import { IgxOverlayService } from '../overlay';
import { ScrollStrategy } from './scroll-strategy';
/**
* On scroll reposition the overlay content.
*/
export class AbsoluteScrollStrategy extends ScrollStrategy {
private _initialized = false;
private _document: Document;
private _overlayService: IgxOverlayService;
private _id: string;
private _scrollContainer: HTMLElement;
private _zone: NgZone;
constructor(scrollContainer?: HTMLElement) {
super();
this._scrollContainer = scrollContainer;
}
/**
* Initializes the strategy. Should be called once
*
* @param document reference to Document object.
* @param overlayService IgxOverlay service to use in this strategy.
* @param id Unique id for this strategy.
* ```typescript
* settings.scrollStrategy.initialize(document, overlay, id);
* ```
*/
public initialize(document: Document, overlayService: IgxOverlayService, id: string) {
if (this._initialized) {
return;
}
this._overlayService = overlayService;
this._id = id;
this._document = document;
this._zone = overlayService.getOverlayById(id).ngZone;
this._initialized = true;
}
/**
* Attaches the strategy
* ```typescript
* settings.scrollStrategy.attach();
* ```
*/
public attach(): void {
if (this._zone) {
this._zone.runOutsideAngular(() => {
this.addScrollEventListener();
});
} else {
this.addScrollEventListener();
}
}
/**
* Detaches the strategy
* ```typescript
* settings.scrollStrategy.detach();
* ```
*/
public detach(): void {
if (this._scrollContainer) {
this._scrollContainer.removeEventListener('scroll', this.onScroll, true);
} else {
// Tired of this thing throwing every other time. Fix it ffs!
this._document?.removeEventListener('scroll', this.onScroll, true);
}
this._initialized = false;
}
private addScrollEventListener() {
if (this._scrollContainer) {
this._scrollContainer.addEventListener('scroll', this.onScroll, true);
} else {
this._document.addEventListener('scroll', this.onScroll, true);
}
}
private onScroll = (e: Event) => {
const overlayInfo = this._overlayService.getOverlayById(this._id);
if (!overlayInfo) {
return;
}
if (!overlayInfo.elementRef.nativeElement.contains(e.target)) {
this._overlayService.reposition(this._id);
}
};
}