Untitled
unknown
typescript
a year ago
5.4 kB
6
Indexable
import { ElementRef, Injectable, Renderer2, RendererFactory2 } from '@angular/core'; import { fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class ResponsivityService { private initState: boolean = false; private renderer: Renderer2; originalElement: ElementRef; children: ElementRef[] = []; savedChildren: ElementRef[] = []; savedBurgerChildren: ElementRef[] = []; noResponsiveElements: ElementRef[] = []; burgerChildren: ElementRef[] = []; burgerElement: ElementRef = null; burgerWidth: number = 0; burgerHidden: boolean = true; reserveConstant: number = 15; constructor(rendererFactory: RendererFactory2) { this.renderer = rendererFactory.createRenderer(null, null); } initResponsivity(headerElement: ElementRef, children: ElementRef[], burgerChildren: ElementRef[], noResponsiveElements: ElementRef[], burgerElement: ElementRef): void { if (!this.initState) { this.settingInitialValues(headerElement, children, burgerChildren, noResponsiveElements, burgerElement); this.saveChildrenReferences(); this.checkElementVisibility(); this.checkWindowResize(); this.initState = true; } } checkElementVisibility(): void { this.showAllChildren(); this.hideAllBurgerChildren(); const childrenToHide = this.getChildrenToHide(); this.hideChildren(childrenToHide); this.showBurgerChildren(childrenToHide); } private settingInitialValues(headerElement: ElementRef, children: ElementRef[], burgerChildren: ElementRef[], noResponsiveElements: ElementRef[], burgerElement: ElementRef): void { this.originalElement = headerElement; this.children = children; this.burgerChildren = burgerChildren; this.noResponsiveElements = noResponsiveElements; this.burgerElement = burgerElement; } private checkWindowResize(): void { fromEvent(window, 'resize').pipe( debounceTime(300) ).subscribe((event: Event) => { this.checkElementVisibility(); }); } private cloneElement(element: ElementRef): ElementRef { const clonedElement = element.nativeElement.cloneNode(true); return new ElementRef(clonedElement); } private saveChildrenReferences(): void { this.children.forEach((child: ElementRef) => { this.savedChildren.push(this.cloneElement(child)); }); this.burgerChildren.forEach((child: ElementRef) => { this.savedBurgerChildren.push(this.cloneElement(child)); }); } private getParentWidth(): number { this.burgerWidth = this.burgerElement.nativeElement.offsetWidth; let noResponsiveChildrenWidth = 0; this.noResponsiveElements.forEach((noResponsiveElement: ElementRef) => { noResponsiveChildrenWidth += noResponsiveElement.nativeElement.offsetWidth; }); return this.originalElement.nativeElement.getBoundingClientRect().width - noResponsiveChildrenWidth - this.burgerWidth - this.reserveConstant; } private getChildrenToHide(): ElementRef[] { const elementsToHide = []; const parentWidth = this.getParentWidth(); let totalChildrenWidth = 0; for (let i = 0; i < this.children.length; i++) { const child = this.children[i]; totalChildrenWidth += child.nativeElement.offsetWidth; if (totalChildrenWidth > parentWidth) { elementsToHide.push(child.nativeElement.nodeName.toLowerCase()); } } return elementsToHide; } private hideChildren(elementsToHide: ElementRef[]): void { if (elementsToHide.length > 0) { elementsToHide.forEach(elementId => { const element = this.children.find(child => child.nativeElement.nodeName.toLowerCase() === elementId); if (element) { element.nativeElement.style.display = 'none'; } }); this.setVisibilityOfBurger(true); } else { this.setVisibilityOfBurger(false); } } private showAllChildren(): void { this.children.forEach((element: ElementRef) => { const savedElement = this.savedChildren.find(child => child.nativeElement.nodeName.toLowerCase() === element.nativeElement.nodeName.toLowerCase()); if (element) { element.nativeElement.style.display = savedElement.nativeElement.style.display; } }); } private hideAllBurgerChildren(): void { this.burgerChildren.forEach((element: ElementRef) => { if (element) { element.nativeElement.style.display = 'none'; } }); } private showBurgerChildren(elementsToShow: ElementRef[]): void { if (elementsToShow.length > 0) { elementsToShow.forEach(elementId => { const element = this.burgerChildren.find(child => child.nativeElement.nodeName.toLowerCase() === elementId); const savedElement = this.savedBurgerChildren.find(child => child.nativeElement.nodeName.toLowerCase() === elementId); if (element) { element.nativeElement.style.display = savedElement.nativeElement.style.display; } }); } } private setVisibilityOfBurger(show: boolean): void { if (show) { this.burgerElement.nativeElement.style.setProperty('display', 'flex', 'important'); this.burgerHidden = false; } else { this.burgerElement.nativeElement.style.setProperty('display', 'none', 'important'); this.burgerHidden = true; } } }
Editor is loading...
Leave a Comment