| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- import {ElementRef} from '@angular/core';
- import extend from 'lodash-es/extend';
- import {IncrementalStackManager} from '@ex-helpers/stack';
- import {bounds} from './bounds';
- interface SizeCollectionItem {
- triggerCheck: () => void;
- startCountdown: () => void;
- callback: (height: number, width: number) => void;
- observer?: MutationObserver;
- id?: number;
- legacy?: boolean;
- }
- const DEFAULT_OPTIONS = {
- attributes: true,
- childList: true,
- characterData: true
- };
- export class ElementWatcher {
- private _watchSizeCollection: any;
- public nativeElement: HTMLElement;
- constructor(ref: HTMLElement | ElementRef) {
- this.nativeElement = ref instanceof ElementRef ? ref.nativeElement : ref;
- }
- watchSize(callback: (height: number, width: number) => void,
- options?: { attributes?: boolean, childList?: boolean, characterData?: boolean },
- params: { timeout?: number, legacy: boolean } = {legacy: false}) {
- if (!this._watchSizeCollection) {
- Object.defineProperty(this, '_watchSizeCollection', {
- enumerable: false,
- configurable: true,
- writable: false,
- value: new IncrementalStackManager<SizeCollectionItem>('id')
- });
- }
- options = extend(DEFAULT_OPTIONS, options);
- let timeout: any;
- let lastHeight: number;
- let lastWidth: number;
- const triggerCheck = () => {
- const sizes = bounds(this.nativeElement).size;
- if (lastWidth === sizes.width && lastHeight === sizes.height) {
- return;
- }
- lastHeight = sizes.height;
- lastWidth = sizes.width;
- callback(sizes.height, sizes.width);
- };
- const startCountdown = () => {
- clearTimeout(timeout);
- timeout = setTimeout(() => {
- triggerCheck();
- }, params.timeout || 100);
- };
- const item = this._watchSizeCollection.add({
- callback,
- startCountdown,
- triggerCheck
- });
- if (MutationObserver && params.legacy === false) {
- const observer = new MutationObserver(mutations => {
- startCountdown();
- });
- item.observer = observer;
- item.legacy = false;
- startCountdown();
- observer.observe(this.nativeElement, options);
- return () => observer.disconnect();
- } else {
- item.legacy = true;
- const checkInterval = setInterval(() => {
- triggerCheck();
- }, 200);
- startCountdown();
- return () => clearInterval(checkInterval);
- }
- }
- triggerSizeCheck() {
- if (this._watchSizeCollection) {
- this._watchSizeCollection.execute('triggerCheck');
- }
- }
- watchChanges(callback: MutationCallback, options: MutationObserverInit) {
- if (MutationObserver) {
- const observer = new MutationObserver(callback);
- observer.observe(this.nativeElement, options);
- return () => observer.disconnect();
- }
- return () => {
- };
- }
- }
- export function watchElement(ref: HTMLElement | ElementRef) {
- return new ElementWatcher(ref);
- }
|