@@ -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