@@ -47,8 +47,10 @@ angular.module('material.components.toolbar', [
47
47
*
48
48
* @param {boolean= } md-scroll-shrink Whether the header should shrink away as
49
49
* the user scrolls down, and reveal itself as the user scrolls up.
50
- * Note: for scrollShrink to work, the toolbar must be a sibling of a
51
- * `md-content` element, placed before it. See the scroll shrink demo.
50
+ * _**Note (1):** for scrollShrink to work, the toolbar must be a sibling of a
51
+ * `md-content` element, placed before it. See the scroll shrink demo._
52
+ * _**Note (2):** The `md-scroll-shrink` attribute is only parsed on component
53
+ * initialization, it does not watch for scope changes._
52
54
*
53
55
*
54
56
* @param {number= } md-shrink-speed-factor How much to change the speed of the toolbar's
@@ -61,84 +63,66 @@ function mdToolbarDirective($$rAF, $mdConstant, $mdUtil, $mdTheming, $animate) {
61
63
62
64
return {
63
65
restrict : 'E' ,
64
- template : '<div ng-transclude></div>' ,
65
- transclude : true ,
66
- controller : angular . noop ,
67
- scope : {
68
- scrollShrink : '=?mdScrollShrink'
69
- } ,
66
+
70
67
link : function ( scope , element , attr ) {
71
68
72
69
$mdTheming ( element ) ;
73
70
74
71
setupScrollShrink ( ) ;
75
72
76
73
function setupScrollShrink ( ) {
74
+
75
+ var toolbarHeight ;
76
+ var contentElement ;
77
+ var disableScrollShrink = angular . noop ;
78
+
77
79
// Current "y" position of scroll
78
- var y = 0 ;
79
80
// Store the last scroll top position
81
+ var y = 0 ;
80
82
var prevScrollTop = 0 ;
81
-
82
83
var shrinkSpeedFactor = attr . mdShrinkSpeedFactor || 0.5 ;
83
84
84
- var toolbarHeight ;
85
- var contentElement ;
86
-
87
85
var debouncedContentScroll = $$rAF . throttle ( onContentScroll ) ;
88
86
var debouncedUpdateHeight = $mdUtil . debounce ( updateToolbarHeight , 5 * 1000 ) ;
89
87
90
- var disableScrollShrink ;
91
-
92
88
// Wait for $mdContentLoaded event from mdContent directive.
93
89
// If the mdContent element is a sibling of our toolbar, hook it up
94
90
// to scroll events.
91
+
95
92
scope . $on ( '$mdContentLoaded' , onMdContentLoad ) ;
96
93
97
94
// If the toolbar is used inside an ng-if statement, we may miss the
98
95
// $mdContentLoaded event, so we attempt to fake it if we have a
99
96
// md-content close enough.
100
- scope . $watch ( 'scrollShrink' , onChangeScrollShrink ) ;
97
+
98
+ attr . $observe ( 'mdScrollShrink' , onChangeScrollShrink ) ;
101
99
102
100
// If the scope is destroyed (which could happen with ng-if), make sure
103
101
// to disable scroll shrinking again
104
- scope . $on ( '$destroy' , function ( ) {
105
- disableScrollShrink ( ) ;
106
- } ) ;
107
102
108
- function onChangeScrollShrink ( scrollShrink ) {
103
+ scope . $on ( '$destroy' , disableScrollShrink ) ;
104
+
105
+ /**
106
+ *
107
+ */
108
+ function onChangeScrollShrink ( shrinkWithScroll ) {
109
109
var closestContent = element . parent ( ) . find ( 'md-content' ) ;
110
110
111
111
// If we have a content element, fake the call; this might still fail
112
112
// if the content element isn't a sibling of the toolbar
113
+
113
114
if ( ! contentElement && closestContent . length ) {
114
115
onMdContentLoad ( null , closestContent ) ;
115
116
}
116
117
117
- if ( contentElement ) {
118
- // Disable only if the attribute's expression evaluates to false
119
- if ( scrollShrink === false ) {
120
- disableScrollShrink ( ) ;
121
- } else {
122
- enableScrollShrink ( ) ;
123
- }
124
- }
125
- }
126
-
127
- function enableScrollShrink ( ) {
128
- contentElement . on ( 'scroll' , debouncedContentScroll ) ;
129
- contentElement . attr ( 'scroll-shrink' , 'true' ) ;
130
-
131
- $$rAF ( updateToolbarHeight ) ;
118
+ // Disable only if the attribute's expression evaluates to false
132
119
133
- return function disableScrollShrink ( ) {
134
- contentElement . off ( 'scroll' , debouncedContentScroll ) ;
135
- contentElement . attr ( 'scroll-shrink' , 'false' ) ;
136
-
137
- $$rAF ( updateToolbarHeight ) ;
138
- }
120
+ if ( shrinkWithScroll ) disableScrollShrink = enableScrollShrink ( ) ;
139
121
}
140
122
141
-
123
+ /**
124
+ *
125
+ */
142
126
function onMdContentLoad ( $event , newContentEl ) {
143
127
// Toolbar and content must be siblings
144
128
if ( newContentEl && element . parent ( ) [ 0 ] === newContentEl . parent ( ) [ 0 ] ) {
@@ -152,24 +136,9 @@ function mdToolbarDirective($$rAF, $mdConstant, $mdUtil, $mdTheming, $animate) {
152
136
}
153
137
}
154
138
155
- function updateToolbarHeight ( ) {
156
- toolbarHeight = element . prop ( 'offsetHeight' ) ;
157
- // Add a negative margin-top the size of the toolbar to the content el.
158
- // The content will start transformed down the toolbarHeight amount,
159
- // so everything looks normal.
160
- //
161
- // As the user scrolls down, the content will be transformed up slowly
162
- // to put the content underneath where the toolbar was.
163
- var margin = ( - toolbarHeight * shrinkSpeedFactor ) + 'px' ;
164
-
165
- contentElement . css ( {
166
- "margin-top" : margin ,
167
- "margin-bottom" : margin
168
- } ) ;
169
-
170
- onContentScroll ( ) ;
171
- }
172
-
139
+ /**
140
+ *
141
+ */
173
142
function onContentScroll ( e ) {
174
143
var scrollTop = e ? e . target . scrollTop : prevScrollTop ;
175
144
@@ -197,6 +166,46 @@ function mdToolbarDirective($$rAF, $mdConstant, $mdUtil, $mdTheming, $animate) {
197
166
198
167
}
199
168
169
+ /**
170
+ *
171
+ */
172
+ function enableScrollShrink ( ) {
173
+ if ( ! contentElement ) return angular . noop ; // no md-content
174
+
175
+ contentElement . on ( 'scroll' , debouncedContentScroll ) ;
176
+ contentElement . attr ( 'scroll-shrink' , 'true' ) ;
177
+
178
+ $$rAF ( updateToolbarHeight ) ;
179
+
180
+ return function disableScrollShrink ( ) {
181
+ contentElement . off ( 'scroll' , debouncedContentScroll ) ;
182
+ contentElement . attr ( 'scroll-shrink' , 'false' ) ;
183
+
184
+ $$rAF ( updateToolbarHeight ) ;
185
+ }
186
+ }
187
+
188
+ /**
189
+ *
190
+ */
191
+ function updateToolbarHeight ( ) {
192
+ toolbarHeight = element . prop ( 'offsetHeight' ) ;
193
+ // Add a negative margin-top the size of the toolbar to the content el.
194
+ // The content will start transformed down the toolbarHeight amount,
195
+ // so everything looks normal.
196
+ //
197
+ // As the user scrolls down, the content will be transformed up slowly
198
+ // to put the content underneath where the toolbar was.
199
+ var margin = ( - toolbarHeight * shrinkSpeedFactor ) + 'px' ;
200
+
201
+ contentElement . css ( {
202
+ "margin-top" : margin ,
203
+ "margin-bottom" : margin
204
+ } ) ;
205
+
206
+ onContentScroll ( ) ;
207
+ }
208
+
200
209
}
201
210
202
211
}
0 commit comments