import { Component, Input, ElementRef, Output, EventEmitter, Renderer2, NgZone, OnInit, OnDestroy, HostBinding, ChangeDetectionStrategy } from '@angular/core'; import { MouseEvent } from '../../events'; @Component({ selector: 'datatable-scroller', template: ` `, host: { class: 'datatable-scroll' }, changeDetection: ChangeDetectionStrategy.OnPush }) export class ScrollerComponent implements OnInit, OnDestroy { @Input() scrollbarV: boolean = false; @Input() scrollbarH: boolean = false; @HostBinding('style.height.px') @Input() scrollHeight: number; @HostBinding('style.width.px') @Input() scrollWidth: number; @Output() scroll: EventEmitter = new EventEmitter(); scrollYPos: number = 0; scrollXPos: number = 0; prevScrollYPos: number = 0; prevScrollXPos: number = 0; element: any; parentElement: any; onScrollListener: any; constructor(private ngZone: NgZone, element: ElementRef, private renderer: Renderer2) { this.element = element.nativeElement; } ngOnInit(): void { // manual bind so we don't always listen if (this.scrollbarV || this.scrollbarH) { const renderer = this.renderer; this.parentElement = renderer.parentNode(renderer.parentNode(this.element)); this.parentElement.addEventListener('scroll', this.onScrolled.bind(this)); } } ngOnDestroy(): void { if (this.scrollbarV || this.scrollbarH) { this.parentElement.removeEventListener('scroll', this.onScrolled.bind(this)); } } setOffset(offsetY: number): void { if (this.parentElement) { this.parentElement.scrollTop = offsetY; } } onScrolled(event: MouseEvent): void { const dom: Element = event.currentTarget; requestAnimationFrame(() => { this.scrollYPos = dom.scrollTop; this.scrollXPos = dom.scrollLeft; this.updateOffset(); }); } updateOffset(): void { let direction: string; if (this.scrollYPos < this.prevScrollYPos) { direction = 'down'; } else if (this.scrollYPos > this.prevScrollYPos) { direction = 'up'; } this.scroll.emit({ direction, scrollYPos: this.scrollYPos, scrollXPos: this.scrollXPos }); this.prevScrollYPos = this.scrollYPos; this.prevScrollXPos = this.scrollXPos; } }