Skip to content

Instantly share code, notes, and snippets.

@MurhafSousli
Created May 6, 2017 01:20
Show Gist options
  • Save MurhafSousli/2757f7a8eb7b7b3e2f458059786acccd to your computer and use it in GitHub Desktop.
Save MurhafSousli/2757f7a8eb7b7b3e2f458059786acccd to your computer and use it in GitHub Desktop.
Affix directive
import {Directive, Input, ElementRef, Renderer} from '@angular/core';
import {WindowService} from "../../window/window.service";
@Directive({
selector: '[affix]'
})
export class AffixDirective {
@Input() affix: any;
parent: HTMLElement;
element: HTMLElement;
constructor(private window: WindowService, elementRef: ElementRef, private renderer: Renderer) {
this.element = elementRef.nativeElement;
}
ngOnInit() {
/** affixConfig must be presented */
if (typeof this.affix === 'undefined') {
throw '[AFFIX]: affixConfig element is not presented!';
}
if (typeof this.affix.parent === 'undefined') {
throw '[AFFIX]: Parent element is not presented!';
}
if (typeof this.affix.top === 'undefined' && typeof this.affix.bottom === 'undefined') {
throw '[AFFIX]: affixConfig must has "top" or "bottom" presented';
}
/** Get parent position */
this.parent = this.affix.parent;
/** Start listen to window scroll */
this.window.scroll.subscribe((e: any) => {
if (e.target && e.target.scrollingElement) {
if (typeof this.affix.top !== 'undefined') {
this.topAffix();
} else if (typeof this.affix.bottom !== 'undefined') {
this.bottomAffix();
}
}
});
}
topAffix() {
if (this.parent.getBoundingClientRect().top <= this.affix.top) {
this.renderer.setElementStyle(this.element, 'position', 'fixed');
this.renderer.setElementStyle(this.element, 'top', `${this.affix.top}px`);
} else {
this.renderer.setElementStyle(this.element, 'position', 'unset');
this.renderer.setElementStyle(this.element, 'top', 'unset');
}
}
bottomAffix() {
if (this.parent.getBoundingClientRect().top + this.affix.bottom <= 0) {
let width = this.parent.getBoundingClientRect().width;
this.renderer.setElementStyle(this.element, 'position', 'fixed');
this.renderer.setElementStyle(this.element, 'bottom', `${this.affix.bottom}px`);
this.renderer.setElementStyle(this.element, 'width', `${width}px`);
} else {
this.renderer.setElementStyle(this.element, 'position', 'unset');
this.renderer.setElementStyle(this.element, 'bottom', 'unset');
this.renderer.setElementStyle(this.element, 'width', `unset`);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment