Skip to content

Commit ab4fd94

Browse files
committed
fix some code according to PR review comments
1 parent c2b3a9f commit ab4fd94

File tree

1 file changed

+68
-61
lines changed

1 file changed

+68
-61
lines changed

src/lib/sticky-header/sticky-header-dir.ts

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,44 @@ export class StickyParentDirective {
2323
})
2424

2525
@Injectable()
26-
export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
27-
26+
export class StickyHeaderDirective implements OnDestroy, AfterViewInit {
27+
28+
/**Set the sticky-header's z-index as 10 in default. Make it as an input
29+
* variable to make user be able to customize the zIndex when
30+
* the sticky-header's zIndex is not the largest in current page.
31+
* Because if the sticky-header's zIndex is not the largest in current page,
32+
* it may be sheltered by other element when being sticked.
33+
*/
2834
@Input('sticky-zIndex') zIndex: number = 10;
29-
@Input('parentRegion') parentRegion: any;
35+
@Input() cdkStickyParentRegion: any;
3036
@Input('scrollRegion') scrollableRegion: any;
3137

3238

33-
private activated = new EventEmitter();
34-
private deactivated = new EventEmitter();
39+
private _activated = new EventEmitter();
40+
private _deactivated = new EventEmitter();
3541

3642
private onScrollBind: EventListener = this.onScroll.bind(this);
3743
private onResizeBind: EventListener = this.onResize.bind(this);
3844
private onTouchMoveBind: EventListener = this.onTouchMove.bind(this);
3945

40-
private stickStartClass: string = 'sticky';
41-
private stickEndClass: string = 'sticky-end';
46+
public STICK_START_CLASS: string = 'sticky';
47+
public STICK_END_CLASS: string = 'sticky-end';
4248
private isStuck: boolean = false;
4349

4450
// the element with the 'md-sticky' tag
45-
private elem: any;
51+
public elem: any;
4652

4753
// the uppercontainer element with the 'md-sticky-viewport' tag
48-
stickyParent: any;
54+
public stickyParent: any;
4955

5056
// the upper scrollable container
51-
private upperScrollableContainer: any;
57+
public upperScrollableContainer: any;
5258

53-
// the original css of the sticky element, used to reset the sticky element when it is being unstick
54-
private originalCss: any;
59+
/**
60+
* the original css of the sticky element, used to reset the sticky element
61+
* when it is being unstuck
62+
*/
63+
public originalCss: any;
5564

5665
// the height of 'stickyParent'
5766
private containerHeight: number;
@@ -62,47 +71,35 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
6271
private containerStart: number;
6372
private scrollFinish: number;
6473

65-
private scrollingWidth: any;
66-
private scrollingRight: any;
74+
private scrollingWidth: number;
75+
private scrollingRight: number;
6776

6877
// the padding of 'elem'
6978
private elementPadding: any;
70-
private paddingNumber: any;
79+
private paddingNumber: number;
7180

7281
// sticky element's width
7382
private width: string = 'auto';
7483

7584
constructor(private element: ElementRef,
76-
public findScroll: Scrollable,
85+
public scrollable: Scrollable,
7786
@Optional() public parentReg: StickyParentDirective) {
7887
this.elem = element.nativeElement;
79-
this.upperScrollableContainer = findScroll.getElementRef().nativeElement;
80-
this.scrollableRegion = findScroll.getElementRef().nativeElement;
88+
this.upperScrollableContainer = scrollable.getElementRef().nativeElement;
89+
this.scrollableRegion = scrollable.getElementRef().nativeElement;
8190
if(parentReg != null) {
82-
this.parentRegion = parentReg.getElementRef().nativeElement;
91+
this.cdkStickyParentRegion = parentReg.getElementRef().nativeElement;
8392
}
8493
}
8594

86-
ngOnInit(): void {
87-
88-
}
89-
9095
ngAfterViewInit(): void {
9196

92-
if(this.parentRegion != null) {
93-
this.stickyParent = this.parentRegion;
97+
if(this.cdkStickyParentRegion != null) {
98+
this.stickyParent = this.cdkStickyParentRegion;
9499
}else {
95100
this.stickyParent = this.elem.parentNode;
96101
}
97102

98-
// // define parent scrollable container as parent element
99-
// this.stickyParent = this.elem.parentNode;
100-
//
101-
// // make sure this.stickyParent is the element with 'sticky-parent' tag
102-
// while (!this.stickyParent.classList.contains('sticky-parent')) {
103-
// this.stickyParent = this.elem.parentNode;
104-
// }
105-
106103
this.originalCss = {
107104
zIndex: this.getCssValue(this.elem, 'zIndex'),
108105
position: this.getCssValue(this.elem, 'position'),
@@ -137,10 +134,10 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
137134
this.upperScrollableContainer.addEventListener('touchmove', this.onTouchMoveBind, false);
138135

139136
Observable.fromEvent(this.upperScrollableContainer, 'scroll')
140-
.subscribe(() => this.onScroll());
137+
.subscribe(() => this.defineRestrictionsAndStick());
141138

142139
Observable.fromEvent(this.upperScrollableContainer, 'touchmove')
143-
.subscribe(() => this.onTouchMove());
140+
.subscribe(() => this.defineRestrictionsAndStick());
144141
}
145142

146143
detach() {
@@ -150,26 +147,31 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
150147
}
151148

152149
onScroll(): void {
153-
this.defineRestrictions();
154-
this.sticker();
150+
this.defineRestrictionsAndStick();
155151
}
156152

157153
onTouchMove(): void {
158-
this.defineRestrictions();
159-
this.sticker();
154+
this.defineRestrictionsAndStick();
160155
}
161156

162157
onResize(): void {
163-
this.defineRestrictions();
164-
this.sticker();
158+
this.defineRestrictionsAndStick();
165159

160+
/**
161+
* If there's already a header being sticked when the page is
162+
* resized. The CSS style of the sticky-header may be not fit
163+
* the resized window. So we need to unstick it then restick it.
164+
*/
166165
if (this.isStuck) {
167-
this.unstickElement();
166+
this.unstuckElement();
168167
this.stickElement();
169168
}
170169
}
171170

172-
// define the restrictions of the sticky header(including stickyWidth, when to start, when to finish)
171+
/**
172+
* define the restrictions of the sticky header(including stickyWidth,
173+
* when to start, when to finish)
174+
*/
173175
defineRestrictions(): void {
174176
let containerTop: any = this.stickyParent.getBoundingClientRect();
175177
this.elemHeight = this.elem.offsetHeight;
@@ -185,18 +187,22 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
185187
this.scrollFinish = this.containerStart + (this.containerHeight - this.elemHeight);
186188
}
187189

188-
// reset element to its original CSS
190+
/**
191+
* reset element to its original CSS
192+
*/
189193
resetElement(): void {
190-
this.elem.classList.remove(this.stickStartClass);
194+
this.elem.classList.remove(this.STICK_START_CLASS);
191195
Object.assign(this.elem.style, this.originalCss);
192196
}
193197

194-
// stuck element, make the element stick to the top of the scrollable container.
198+
/**
199+
* stuck element, make the element stick to the top of the scrollable container.
200+
*/
195201
stickElement(): void {
196202
this.isStuck = true;
197203

198-
this.elem.classList.remove(this.stickEndClass);
199-
this.elem.classList.add(this.stickStartClass);
204+
this.elem.classList.remove(this.STICK_END_CLASS);
205+
this.elem.classList.add(this.STICK_START_CLASS);
200206

201207
/** Have to add the translate3d function for the sticky element's css style.
202208
* Because iPhone and iPad's browser is using its owning rendering engine. And
@@ -238,14 +244,16 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
238244
this.elem.style.setProperty('left', this.upperScrollableContainer.offsetLeft + 'px');
239245
this.elem.style.setProperty('width', this.scrollingWidth + 'px');
240246

241-
this.activated.next(this.elem);
247+
this._activated.next(this.elem);
242248
}
243249

244-
// unstuck element
245-
unstickElement(): void {
250+
/**
251+
* unstuck element
252+
*/
253+
unstuckElement(): void {
246254
this.isStuck = false;
247255

248-
this.elem.classList.add(this.stickEndClass);
256+
this.elem.classList.add(this.STICK_END_CLASS);
249257

250258
this.stickyParent.style.position = 'relative';
251259
this.elem.style.position = 'absolute';
@@ -255,23 +263,17 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
255263
this.elem.style.bottom = 0;
256264
this.elem.style.width = this.width;
257265

258-
this.deactivated.next(this.elem);
266+
this._deactivated.next(this.elem);
259267
}
260268

261269

262270
sticker(): void {
263-
// detecting when a container's height changes
264-
let currentContainerHeight: number = this.getCssNumber(this.stickyParent, 'height');
265-
if (currentContainerHeight !== this.containerHeight) {
266-
this.defineRestrictions();
267-
}
268-
269271
let currentPosition: number = this.upperScrollableContainer.offsetTop;
270272

271273
// unstick when the element is scrolled out of the sticky region
272274
if (this.isStuck && (currentPosition < this.containerStart || currentPosition > this.scrollFinish) || currentPosition >= this.scrollFinish) {
273275
this.resetElement();
274-
if (currentPosition >= this.scrollFinish) this.unstickElement();
276+
if (currentPosition >= this.scrollFinish) this.unstuckElement();
275277
this.isStuck = false;
276278
}
277279
// stick when the element is within the sticky region
@@ -280,6 +282,11 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
280282
}
281283
}
282284

285+
defineRestrictionsAndStick(): void {
286+
this.defineRestrictions();
287+
this.sticker();
288+
}
289+
283290

284291
private getCssValue(element: any, property: string): any {
285292
let result: any = '';
@@ -295,4 +302,4 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
295302
private getCssNumber(element: any, property: string): number {
296303
return parseInt(this.getCssValue(element, property), 10) || 0;
297304
}
298-
}
305+
}

0 commit comments

Comments
 (0)