@@ -74,10 +74,7 @@ export default class Visibility extends Component {
74
74
offset : PropTypes . oneOfType ( [
75
75
PropTypes . number ,
76
76
PropTypes . string ,
77
- PropTypes . arrayOf ( PropTypes . oneOfType ( [
78
- PropTypes . number ,
79
- PropTypes . string ,
80
- ] ) ) ,
77
+ PropTypes . arrayOf ( PropTypes . oneOfType ( [ PropTypes . number , PropTypes . string ] ) ) ,
81
78
] ) ,
82
79
83
80
/** When set to false a callback will occur each time an element passes the threshold for a condition. */
@@ -157,13 +154,21 @@ export default class Visibility extends Component {
157
154
* @param {object } data - All props.
158
155
*/
159
156
onUpdate : PropTypes . func ,
157
+
158
+ /**
159
+ * Allows to choose the mode of the position calculations:
160
+ * - `events` - (default) update and fire callbacks only on scroll/resize events
161
+ * - `repaint` - update and fire callbacks on browser repaint (animation frames)
162
+ */
163
+ updateOn : PropTypes . oneOf ( [ 'events' , 'repaint' ] ) ,
160
164
}
161
165
162
166
static defaultProps = {
163
167
context : isBrowser ( ) ? window : null ,
164
168
continuous : false ,
165
169
offset : [ 0 , 0 ] ,
166
170
once : true ,
171
+ updateOn : 'events' ,
167
172
}
168
173
169
174
static _meta = {
@@ -188,24 +193,27 @@ export default class Visibility extends Component {
188
193
// Lifecycle
189
194
// ----------------------------------------
190
195
191
- componentWillReceiveProps ( { continuous, once, context } ) {
192
- const cleanHappened = continuous !== this . props . continuous || once !== this . props . once
196
+ componentWillReceiveProps ( { continuous, once, context, updateOn } ) {
197
+ const cleanHappened =
198
+ continuous !== this . props . continuous ||
199
+ once !== this . props . once ||
200
+ updateOn !== this . props . updateOn
193
201
194
202
// Heads up! We should clean up array of happened callbacks, if values of these props are changed
195
203
if ( cleanHappened ) this . firedCallbacks = [ ]
196
204
197
- if ( this . props . context !== context ) {
205
+ if ( context !== this . props . context || updateOn !== this . props . updateOn ) {
198
206
this . unattachHandlers ( this . props . context )
199
- this . attachHandlers ( context )
207
+ this . attachHandlers ( context , updateOn )
200
208
}
201
209
}
202
210
203
211
componentDidMount ( ) {
204
212
if ( ! isBrowser ( ) ) return
205
- const { context, fireOnMount } = this . props
213
+ const { context, fireOnMount, updateOn } = this . props
206
214
207
215
this . pageYOffset = window . pageYOffset
208
- this . attachHandlers ( context )
216
+ this . attachHandlers ( context , updateOn )
209
217
210
218
if ( fireOnMount ) this . update ( )
211
219
}
@@ -214,21 +222,30 @@ export default class Visibility extends Component {
214
222
const { context } = this . props
215
223
216
224
this . unattachHandlers ( context )
217
- if ( this . frameId ) cancelAnimationFrame ( this . frameId )
218
225
}
219
226
220
- attachHandlers ( context ) {
221
- if ( context ) {
222
- eventStack . sub ( 'resize' , this . handleUpdate , { target : context } )
223
- eventStack . sub ( 'scroll' , this . handleUpdate , { target : context } )
227
+ attachHandlers ( context , updateOn ) {
228
+ if ( updateOn === 'events' ) {
229
+ if ( context ) {
230
+ eventStack . sub ( 'resize' , this . handleUpdate , { target : context } )
231
+ eventStack . sub ( 'scroll' , this . handleUpdate , { target : context } )
232
+ }
233
+
234
+ return
224
235
}
236
+
237
+ // Heads up!
238
+ // We will deal with `repaint` there
239
+ this . handleUpdate ( )
225
240
}
226
241
227
242
unattachHandlers ( context ) {
228
243
if ( context ) {
229
244
eventStack . unsub ( 'resize' , this . handleUpdate , { target : context } )
230
245
eventStack . unsub ( 'scroll' , this . handleUpdate , { target : context } )
231
246
}
247
+
248
+ if ( this . frameId ) cancelAnimationFrame ( this . frameId )
232
249
}
233
250
234
251
// ----------------------------------------
@@ -308,6 +325,7 @@ export default class Visibility extends Component {
308
325
onTopVisibleReverse,
309
326
onOffScreen,
310
327
onOnScreen,
328
+ updateOn,
311
329
} = this . props
312
330
const forward = {
313
331
bottomPassed : { callback : onBottomPassed , name : 'onBottomPassed' } ,
@@ -333,6 +351,8 @@ export default class Visibility extends Component {
333
351
// Heads up! Reverse callbacks should be fired first
334
352
_ . forEach ( reverse , ( data , value ) => this . fire ( data , value , true ) )
335
353
_ . forEach ( forward , ( data , value ) => this . fire ( data , value ) )
354
+
355
+ if ( updateOn === 'repaint' ) this . handleUpdate ( )
336
356
}
337
357
338
358
// ----------------------------------------
@@ -392,6 +412,10 @@ export default class Visibility extends Component {
392
412
const ElementType = getElementType ( Visibility , this . props )
393
413
const rest = getUnhandledProps ( Visibility , this . props )
394
414
395
- return < ElementType { ...rest } ref = { this . handleRef } > { children } </ ElementType >
415
+ return (
416
+ < ElementType { ...rest } ref = { this . handleRef } >
417
+ { children }
418
+ </ ElementType >
419
+ )
396
420
}
397
421
}
0 commit comments