@@ -23,35 +23,44 @@ export class StickyParentDirective {
23
23
} )
24
24
25
25
@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
+ */
28
34
@Input ( 'sticky-zIndex' ) zIndex : number = 10 ;
29
- @Input ( 'parentRegion' ) parentRegion : any ;
35
+ @Input ( ) cdkStickyParentRegion : any ;
30
36
@Input ( 'scrollRegion' ) scrollableRegion : any ;
31
37
32
38
33
- private activated = new EventEmitter ( ) ;
34
- private deactivated = new EventEmitter ( ) ;
39
+ private _activated = new EventEmitter ( ) ;
40
+ private _deactivated = new EventEmitter ( ) ;
35
41
36
42
private onScrollBind : EventListener = this . onScroll . bind ( this ) ;
37
43
private onResizeBind : EventListener = this . onResize . bind ( this ) ;
38
44
private onTouchMoveBind : EventListener = this . onTouchMove . bind ( this ) ;
39
45
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' ;
42
48
private isStuck : boolean = false ;
43
49
44
50
// the element with the 'md-sticky' tag
45
- private elem : any ;
51
+ public elem : any ;
46
52
47
53
// the uppercontainer element with the 'md-sticky-viewport' tag
48
- stickyParent : any ;
54
+ public stickyParent : any ;
49
55
50
56
// the upper scrollable container
51
- private upperScrollableContainer : any ;
57
+ public upperScrollableContainer : any ;
52
58
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 ;
55
64
56
65
// the height of 'stickyParent'
57
66
private containerHeight : number ;
@@ -62,47 +71,35 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
62
71
private containerStart : number ;
63
72
private scrollFinish : number ;
64
73
65
- private scrollingWidth : any ;
66
- private scrollingRight : any ;
74
+ private scrollingWidth : number ;
75
+ private scrollingRight : number ;
67
76
68
77
// the padding of 'elem'
69
78
private elementPadding : any ;
70
- private paddingNumber : any ;
79
+ private paddingNumber : number ;
71
80
72
81
// sticky element's width
73
82
private width : string = 'auto' ;
74
83
75
84
constructor ( private element : ElementRef ,
76
- public findScroll : Scrollable ,
85
+ public scrollable : Scrollable ,
77
86
@Optional ( ) public parentReg : StickyParentDirective ) {
78
87
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 ;
81
90
if ( parentReg != null ) {
82
- this . parentRegion = parentReg . getElementRef ( ) . nativeElement ;
91
+ this . cdkStickyParentRegion = parentReg . getElementRef ( ) . nativeElement ;
83
92
}
84
93
}
85
94
86
- ngOnInit ( ) : void {
87
-
88
- }
89
-
90
95
ngAfterViewInit ( ) : void {
91
96
92
- if ( this . parentRegion != null ) {
93
- this . stickyParent = this . parentRegion ;
97
+ if ( this . cdkStickyParentRegion != null ) {
98
+ this . stickyParent = this . cdkStickyParentRegion ;
94
99
} else {
95
100
this . stickyParent = this . elem . parentNode ;
96
101
}
97
102
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
-
106
103
this . originalCss = {
107
104
zIndex : this . getCssValue ( this . elem , 'zIndex' ) ,
108
105
position : this . getCssValue ( this . elem , 'position' ) ,
@@ -137,10 +134,10 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
137
134
this . upperScrollableContainer . addEventListener ( 'touchmove' , this . onTouchMoveBind , false ) ;
138
135
139
136
Observable . fromEvent ( this . upperScrollableContainer , 'scroll' )
140
- . subscribe ( ( ) => this . onScroll ( ) ) ;
137
+ . subscribe ( ( ) => this . defineRestrictionsAndStick ( ) ) ;
141
138
142
139
Observable . fromEvent ( this . upperScrollableContainer , 'touchmove' )
143
- . subscribe ( ( ) => this . onTouchMove ( ) ) ;
140
+ . subscribe ( ( ) => this . defineRestrictionsAndStick ( ) ) ;
144
141
}
145
142
146
143
detach ( ) {
@@ -150,26 +147,31 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
150
147
}
151
148
152
149
onScroll ( ) : void {
153
- this . defineRestrictions ( ) ;
154
- this . sticker ( ) ;
150
+ this . defineRestrictionsAndStick ( ) ;
155
151
}
156
152
157
153
onTouchMove ( ) : void {
158
- this . defineRestrictions ( ) ;
159
- this . sticker ( ) ;
154
+ this . defineRestrictionsAndStick ( ) ;
160
155
}
161
156
162
157
onResize ( ) : void {
163
- this . defineRestrictions ( ) ;
164
- this . sticker ( ) ;
158
+ this . defineRestrictionsAndStick ( ) ;
165
159
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
+ */
166
165
if ( this . isStuck ) {
167
- this . unstickElement ( ) ;
166
+ this . unstuckElement ( ) ;
168
167
this . stickElement ( ) ;
169
168
}
170
169
}
171
170
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
+ */
173
175
defineRestrictions ( ) : void {
174
176
let containerTop : any = this . stickyParent . getBoundingClientRect ( ) ;
175
177
this . elemHeight = this . elem . offsetHeight ;
@@ -185,18 +187,22 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
185
187
this . scrollFinish = this . containerStart + ( this . containerHeight - this . elemHeight ) ;
186
188
}
187
189
188
- // reset element to its original CSS
190
+ /**
191
+ * reset element to its original CSS
192
+ */
189
193
resetElement ( ) : void {
190
- this . elem . classList . remove ( this . stickStartClass ) ;
194
+ this . elem . classList . remove ( this . STICK_START_CLASS ) ;
191
195
Object . assign ( this . elem . style , this . originalCss ) ;
192
196
}
193
197
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
+ */
195
201
stickElement ( ) : void {
196
202
this . isStuck = true ;
197
203
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 ) ;
200
206
201
207
/** Have to add the translate3d function for the sticky element's css style.
202
208
* Because iPhone and iPad's browser is using its owning rendering engine. And
@@ -238,14 +244,16 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
238
244
this . elem . style . setProperty ( 'left' , this . upperScrollableContainer . offsetLeft + 'px' ) ;
239
245
this . elem . style . setProperty ( 'width' , this . scrollingWidth + 'px' ) ;
240
246
241
- this . activated . next ( this . elem ) ;
247
+ this . _activated . next ( this . elem ) ;
242
248
}
243
249
244
- // unstuck element
245
- unstickElement ( ) : void {
250
+ /**
251
+ * unstuck element
252
+ */
253
+ unstuckElement ( ) : void {
246
254
this . isStuck = false ;
247
255
248
- this . elem . classList . add ( this . stickEndClass ) ;
256
+ this . elem . classList . add ( this . STICK_END_CLASS ) ;
249
257
250
258
this . stickyParent . style . position = 'relative' ;
251
259
this . elem . style . position = 'absolute' ;
@@ -255,23 +263,17 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
255
263
this . elem . style . bottom = 0 ;
256
264
this . elem . style . width = this . width ;
257
265
258
- this . deactivated . next ( this . elem ) ;
266
+ this . _deactivated . next ( this . elem ) ;
259
267
}
260
268
261
269
262
270
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
-
269
271
let currentPosition : number = this . upperScrollableContainer . offsetTop ;
270
272
271
273
// unstick when the element is scrolled out of the sticky region
272
274
if ( this . isStuck && ( currentPosition < this . containerStart || currentPosition > this . scrollFinish ) || currentPosition >= this . scrollFinish ) {
273
275
this . resetElement ( ) ;
274
- if ( currentPosition >= this . scrollFinish ) this . unstickElement ( ) ;
276
+ if ( currentPosition >= this . scrollFinish ) this . unstuckElement ( ) ;
275
277
this . isStuck = false ;
276
278
}
277
279
// stick when the element is within the sticky region
@@ -280,6 +282,11 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
280
282
}
281
283
}
282
284
285
+ defineRestrictionsAndStick ( ) : void {
286
+ this . defineRestrictions ( ) ;
287
+ this . sticker ( ) ;
288
+ }
289
+
283
290
284
291
private getCssValue ( element : any , property : string ) : any {
285
292
let result : any = '' ;
@@ -295,4 +302,4 @@ export class StickyHeaderDirective implements OnInit, OnDestroy, AfterViewInit {
295
302
private getCssNumber ( element : any , property : string ) : number {
296
303
return parseInt ( this . getCssValue ( element , property ) , 10 ) || 0 ;
297
304
}
298
- }
305
+ }
0 commit comments