react-lazy-load-image-component 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/build/index.js +295 -282
- package/package.json +1 -1
- package/src/components/LazyLoadComponent.spec.js +2 -0
- package/src/components/LazyLoadImage.jsx +13 -2
- package/src/components/PlaceholderWithoutTracking.jsx +46 -38
- package/src/components/PlaceholderWithoutTracking.spec.js +2 -0
- package/src/effects/opacity.css +0 -1
package/README.md
CHANGED
@@ -77,6 +77,7 @@ export default MyImage;
|
|
77
77
|
| useIntersectionObserver | `Boolean` | true | Whether to use browser's IntersectionObserver when available. |
|
78
78
|
| visibleByDefault | `Boolean` | false | Whether the image must be visible from the beginning. |
|
79
79
|
| wrapperClassName | `String` | | In some occasions (for example, when using a placeholderSrc) a wrapper span tag is rendered. This prop allows setting a class to that element. |
|
80
|
+
| wrapperProps | `Object` | null | Props that should be passed to the wrapper span when it is rendered (for example, when using placeholderSrc or effect) |
|
80
81
|
| ... | | | Any other image attribute |
|
81
82
|
|
82
83
|
|
@@ -146,7 +147,6 @@ export default Article;
|
|
146
147
|
| useIntersectionObserver | `Boolean` | true | Whether to use browser's IntersectionObserver when available. |
|
147
148
|
| visibleByDefault | `Boolean` | false | Whether the component must be visible from the beginning. |
|
148
149
|
|
149
|
-
|
150
150
|
## Using `trackWindowScroll` HOC to improve performance
|
151
151
|
|
152
152
|
When you have many elements to lazy load in the same page, you might get poor performance because each one is listening to the scroll/resize events. In that case, it's better to wrap the deepest common parent of those components with a HOC to track those events (`trackWindowScroll`).
|
@@ -193,6 +193,7 @@ You must set the prop `scrollPosition` to the lazy load components. This way, th
|
|
193
193
|
| placeholder | `ReactClass` | `<span>` | React element to use as a placeholder. |
|
194
194
|
| threshold | `Number` | 100 | Threshold in pixels. So the image starts loading before it appears in the viewport. |
|
195
195
|
| visibleByDefault | `Boolean` | false | Whether the image must be visible from the beginning. |
|
196
|
+
| wrapperProps | `Object` | null | Props that should be passed to the wrapper span when it is rendered (for example, when using placeholderSrc or effect) |
|
196
197
|
| ... | | | Any other image attribute |
|
197
198
|
|
198
199
|
Component wrapped with `trackWindowScroll` (in the example, `Gallery`)
|
package/build/index.js
CHANGED
@@ -98,8 +98,8 @@ module.exports = (function(e) {
|
|
98
98
|
o = u(r(0)),
|
99
99
|
i = r(1),
|
100
100
|
a = u(r(4)),
|
101
|
-
|
102
|
-
|
101
|
+
s = u(r(12)),
|
102
|
+
l = u(r(2));
|
103
103
|
function u(e) {
|
104
104
|
return e && e.__esModule ? e : { default: e };
|
105
105
|
}
|
@@ -193,7 +193,7 @@ module.exports = (function(e) {
|
|
193
193
|
d = e.useIntersectionObserver,
|
194
194
|
y = e.width;
|
195
195
|
return this.isScrollTracked ||
|
196
|
-
(d && (0,
|
196
|
+
(d && (0, l.default)())
|
197
197
|
? o.default.createElement(a.default, {
|
198
198
|
className: t,
|
199
199
|
height: i,
|
@@ -205,7 +205,7 @@ module.exports = (function(e) {
|
|
205
205
|
useIntersectionObserver: d,
|
206
206
|
width: y,
|
207
207
|
})
|
208
|
-
: o.default.createElement(
|
208
|
+
: o.default.createElement(s.default, {
|
209
209
|
className: t,
|
210
210
|
delayMethod: r,
|
211
211
|
delayTime: n,
|
@@ -270,20 +270,34 @@ module.exports = (function(e) {
|
|
270
270
|
})(),
|
271
271
|
i = u(r(0)),
|
272
272
|
a = u(r(5)),
|
273
|
-
|
274
|
-
|
273
|
+
s = r(1),
|
274
|
+
l = u(r(2));
|
275
275
|
function u(e) {
|
276
276
|
return e && e.__esModule ? e : { default: e };
|
277
277
|
}
|
278
|
-
var c =
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
278
|
+
var c = function(e) {
|
279
|
+
e.forEach(function(e) {
|
280
|
+
e.isIntersecting && e.target.onVisible();
|
281
|
+
});
|
282
|
+
},
|
283
|
+
f = {},
|
284
|
+
p = function(e) {
|
285
|
+
return (
|
286
|
+
(f[e] =
|
287
|
+
f[e] ||
|
288
|
+
new IntersectionObserver(c, { rootMargin: e + 'px' })),
|
289
|
+
f[e]
|
290
|
+
);
|
291
|
+
},
|
292
|
+
d = (function(e) {
|
293
|
+
function t(e) {
|
294
|
+
!(function(e, t) {
|
295
|
+
if (!(e instanceof t))
|
296
|
+
throw new TypeError(
|
297
|
+
'Cannot call a class as a function'
|
298
|
+
);
|
299
|
+
})(this, t);
|
300
|
+
var r = (function(e, t) {
|
287
301
|
if (!e)
|
288
302
|
throw new ReferenceError(
|
289
303
|
"this hasn't been initialised - super() hasn't been called"
|
@@ -295,205 +309,195 @@ module.exports = (function(e) {
|
|
295
309
|
})(
|
296
310
|
this,
|
297
311
|
(t.__proto__ || Object.getPrototypeOf(t)).call(this, e)
|
298
|
-
),
|
299
|
-
n =
|
300
|
-
!e.scrollPosition &&
|
301
|
-
e.useIntersectionObserver &&
|
302
|
-
(0, s.default)();
|
303
|
-
if (((r.LAZY_LOAD_OBSERVER = { supportsObserver: n }), n)) {
|
304
|
-
var o = e.threshold;
|
305
|
-
r.LAZY_LOAD_OBSERVER.observer = new IntersectionObserver(
|
306
|
-
r.checkIntersections,
|
307
|
-
{ rootMargin: o + 'px' }
|
308
312
|
);
|
313
|
+
if (
|
314
|
+
((r.supportsObserver =
|
315
|
+
!e.scrollPosition &&
|
316
|
+
e.useIntersectionObserver &&
|
317
|
+
(0, l.default)()),
|
318
|
+
r.supportsObserver)
|
319
|
+
) {
|
320
|
+
var n = e.threshold;
|
321
|
+
r.observer = p(n);
|
322
|
+
}
|
323
|
+
return r;
|
309
324
|
}
|
310
|
-
return
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
+
return (
|
326
|
+
(function(e, t) {
|
327
|
+
if ('function' != typeof t && null !== t)
|
328
|
+
throw new TypeError(
|
329
|
+
'Super expression must either be null or a function, not ' +
|
330
|
+
typeof t
|
331
|
+
);
|
332
|
+
(e.prototype = Object.create(t && t.prototype, {
|
333
|
+
constructor: {
|
334
|
+
value: e,
|
335
|
+
enumerable: !1,
|
336
|
+
writable: !0,
|
337
|
+
configurable: !0,
|
338
|
+
},
|
339
|
+
})),
|
340
|
+
t &&
|
341
|
+
(Object.setPrototypeOf
|
342
|
+
? Object.setPrototypeOf(e, t)
|
343
|
+
: (e.__proto__ = t));
|
344
|
+
})(t, e),
|
345
|
+
o(t, [
|
346
|
+
{
|
347
|
+
key: 'componentDidMount',
|
348
|
+
value: function() {
|
349
|
+
this.placeholder &&
|
350
|
+
this.observer &&
|
351
|
+
((this.placeholder.onVisible = this.props.onVisible),
|
352
|
+
this.observer.observe(this.placeholder)),
|
353
|
+
this.supportsObserver ||
|
354
|
+
this.updateVisibility();
|
355
|
+
},
|
325
356
|
},
|
326
|
-
|
327
|
-
|
328
|
-
(
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
o(t, [
|
333
|
-
{
|
334
|
-
key: 'checkIntersections',
|
335
|
-
value: function(e) {
|
336
|
-
e.forEach(function(e) {
|
337
|
-
e.isIntersecting && e.target.onVisible();
|
338
|
-
});
|
357
|
+
{
|
358
|
+
key: 'componentWillUnmount',
|
359
|
+
value: function() {
|
360
|
+
this.observer &&
|
361
|
+
this.observer.unobserve(this.placeholder);
|
362
|
+
},
|
339
363
|
},
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
this.placeholder &&
|
345
|
-
this.LAZY_LOAD_OBSERVER &&
|
346
|
-
this.LAZY_LOAD_OBSERVER.observer &&
|
347
|
-
((this.placeholder.onVisible = this.props.onVisible),
|
348
|
-
this.LAZY_LOAD_OBSERVER.observer.observe(
|
349
|
-
this.placeholder
|
350
|
-
)),
|
351
|
-
this.LAZY_LOAD_OBSERVER &&
|
352
|
-
!this.LAZY_LOAD_OBSERVER.supportsObserver &&
|
364
|
+
{
|
365
|
+
key: 'componentDidUpdate',
|
366
|
+
value: function() {
|
367
|
+
this.supportsObserver ||
|
353
368
|
this.updateVisibility();
|
369
|
+
},
|
354
370
|
},
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
.
|
384
|
-
|
385
|
-
left
|
386
|
-
|
387
|
-
r.getPropertyValue('margin-left'),
|
388
|
-
10
|
389
|
-
) || 0,
|
390
|
-
top:
|
391
|
-
parseInt(
|
392
|
-
r.getPropertyValue('margin-top'),
|
393
|
-
10
|
394
|
-
) || 0,
|
371
|
+
{
|
372
|
+
key: 'getPlaceholderBoundingBox',
|
373
|
+
value: function() {
|
374
|
+
var e =
|
375
|
+
arguments.length > 0 &&
|
376
|
+
void 0 !== arguments[0]
|
377
|
+
? arguments[0]
|
378
|
+
: this.props.scrollPosition,
|
379
|
+
t = this.placeholder.getBoundingClientRect(),
|
380
|
+
r = a.default.findDOMNode(this.placeholder)
|
381
|
+
.style,
|
382
|
+
n = {
|
383
|
+
left:
|
384
|
+
parseInt(
|
385
|
+
r.getPropertyValue(
|
386
|
+
'margin-left'
|
387
|
+
),
|
388
|
+
10
|
389
|
+
) || 0,
|
390
|
+
top:
|
391
|
+
parseInt(
|
392
|
+
r.getPropertyValue(
|
393
|
+
'margin-top'
|
394
|
+
),
|
395
|
+
10
|
396
|
+
) || 0,
|
397
|
+
};
|
398
|
+
return {
|
399
|
+
bottom: e.y + t.bottom + n.top,
|
400
|
+
left: e.x + t.left + n.left,
|
401
|
+
right: e.x + t.right + n.left,
|
402
|
+
top: e.y + t.top + n.top,
|
395
403
|
};
|
396
|
-
|
397
|
-
bottom: e.y + t.bottom + n.top,
|
398
|
-
left: e.x + t.left + n.left,
|
399
|
-
right: e.x + t.right + n.left,
|
400
|
-
top: e.y + t.top + n.top,
|
401
|
-
};
|
404
|
+
},
|
402
405
|
},
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
406
|
+
{
|
407
|
+
key: 'isPlaceholderInViewport',
|
408
|
+
value: function() {
|
409
|
+
if (
|
410
|
+
'undefined' == typeof window ||
|
411
|
+
!this.placeholder
|
412
|
+
)
|
413
|
+
return !1;
|
414
|
+
var e = this.props,
|
415
|
+
t = e.scrollPosition,
|
416
|
+
r = e.threshold,
|
417
|
+
n = this.getPlaceholderBoundingBox(t),
|
418
|
+
o = t.y + window.innerHeight,
|
419
|
+
i = t.x,
|
420
|
+
a = t.x + window.innerWidth,
|
421
|
+
s = t.y;
|
422
|
+
return Boolean(
|
423
|
+
s - r <= n.bottom &&
|
424
|
+
o + r >= n.top &&
|
425
|
+
i - r <= n.right &&
|
426
|
+
a + r >= n.left
|
427
|
+
);
|
428
|
+
},
|
426
429
|
},
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
430
|
+
{
|
431
|
+
key: 'updateVisibility',
|
432
|
+
value: function() {
|
433
|
+
this.isPlaceholderInViewport() &&
|
434
|
+
this.props.onVisible();
|
435
|
+
},
|
433
436
|
},
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
? i.default.cloneElement(a, {
|
437
|
+
{
|
438
|
+
key: 'render',
|
439
|
+
value: function() {
|
440
|
+
var e = this,
|
441
|
+
t = this.props,
|
442
|
+
r = t.className,
|
443
|
+
o = t.height,
|
444
|
+
a = t.placeholder,
|
445
|
+
s = t.style,
|
446
|
+
l = t.width;
|
447
|
+
if (a && 'function' != typeof a.type)
|
448
|
+
return i.default.cloneElement(a, {
|
447
449
|
ref: function(t) {
|
448
450
|
return (e.placeholder = t);
|
449
451
|
},
|
450
|
-
|
451
|
-
:
|
452
|
+
});
|
453
|
+
var u = n({ display: 'inline-block' }, s);
|
454
|
+
return (
|
455
|
+
void 0 !== l && (u.width = l),
|
456
|
+
void 0 !== o && (u.height = o),
|
457
|
+
i.default.createElement(
|
452
458
|
'span',
|
453
459
|
{
|
454
460
|
className: r,
|
455
461
|
ref: function(t) {
|
456
462
|
return (e.placeholder = t);
|
457
463
|
},
|
458
|
-
style:
|
459
|
-
{
|
460
|
-
display: 'inline-block',
|
461
|
-
height: o,
|
462
|
-
width: s,
|
463
|
-
},
|
464
|
-
l
|
465
|
-
),
|
464
|
+
style: u,
|
466
465
|
},
|
467
466
|
a
|
468
|
-
|
467
|
+
)
|
468
|
+
);
|
469
|
+
},
|
469
470
|
},
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
);
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
471
|
+
]),
|
472
|
+
t
|
473
|
+
);
|
474
|
+
})(i.default.Component);
|
475
|
+
(d.propTypes = {
|
476
|
+
onVisible: s.PropTypes.func.isRequired,
|
477
|
+
className: s.PropTypes.string,
|
478
|
+
height: s.PropTypes.oneOfType([
|
479
|
+
s.PropTypes.number,
|
480
|
+
s.PropTypes.string,
|
481
|
+
]),
|
482
|
+
placeholder: s.PropTypes.element,
|
483
|
+
threshold: s.PropTypes.number,
|
484
|
+
useIntersectionObserver: s.PropTypes.bool,
|
485
|
+
scrollPosition: s.PropTypes.shape({
|
486
|
+
x: s.PropTypes.number.isRequired,
|
487
|
+
y: s.PropTypes.number.isRequired,
|
485
488
|
}),
|
486
|
-
width:
|
489
|
+
width: s.PropTypes.oneOfType([
|
490
|
+
s.PropTypes.number,
|
491
|
+
s.PropTypes.string,
|
492
|
+
]),
|
487
493
|
}),
|
488
|
-
(
|
494
|
+
(d.defaultProps = {
|
489
495
|
className: '',
|
490
|
-
height: 0,
|
491
496
|
placeholder: null,
|
492
497
|
threshold: 100,
|
493
498
|
useIntersectionObserver: !0,
|
494
|
-
width: 0,
|
495
499
|
}),
|
496
|
-
(t.default =
|
500
|
+
(t.default = d);
|
497
501
|
},
|
498
502
|
function(e, t) {
|
499
503
|
e.exports = require('react-dom');
|
@@ -528,8 +532,8 @@ module.exports = (function(e) {
|
|
528
532
|
})(),
|
529
533
|
i = p(r(0)),
|
530
534
|
a = p(r(5)),
|
531
|
-
|
532
|
-
|
535
|
+
s = r(1),
|
536
|
+
l = p(r(13)),
|
533
537
|
u = p(r(14)),
|
534
538
|
c = p(r(2)),
|
535
539
|
f = p(r(15));
|
@@ -577,7 +581,7 @@ module.exports = (function(e) {
|
|
577
581
|
var n = t.onChangeScroll.bind(t);
|
578
582
|
return (
|
579
583
|
'debounce' === e.delayMethod
|
580
|
-
? (t.delayedScroll = (0,
|
584
|
+
? (t.delayedScroll = (0, l.default)(n, e.delayTime))
|
581
585
|
: 'throttle' === e.delayMethod &&
|
582
586
|
(t.delayedScroll = (0, u.default)(
|
583
587
|
n,
|
@@ -731,9 +735,9 @@ module.exports = (function(e) {
|
|
731
735
|
})(i.default.Component);
|
732
736
|
return (
|
733
737
|
(t.propTypes = {
|
734
|
-
delayMethod:
|
735
|
-
delayTime:
|
736
|
-
useIntersectionObserver:
|
738
|
+
delayMethod: s.PropTypes.oneOf(['debounce', 'throttle']),
|
739
|
+
delayTime: s.PropTypes.number,
|
740
|
+
useIntersectionObserver: s.PropTypes.bool,
|
737
741
|
}),
|
738
742
|
(t.defaultProps = {
|
739
743
|
delayMethod: 'throttle',
|
@@ -798,10 +802,10 @@ module.exports = (function(e) {
|
|
798
802
|
return r && e(t.prototype, r), n && e(t, n), t;
|
799
803
|
};
|
800
804
|
})(),
|
801
|
-
i =
|
805
|
+
i = l(r(0)),
|
802
806
|
a = r(1),
|
803
|
-
|
804
|
-
function
|
807
|
+
s = l(r(3));
|
808
|
+
function l(e) {
|
805
809
|
return e && e.__esModule ? e : { default: e };
|
806
810
|
}
|
807
811
|
var u = (function(e) {
|
@@ -877,6 +881,7 @@ module.exports = (function(e) {
|
|
877
881
|
e.useIntersectionObserver,
|
878
882
|
e.visibleByDefault,
|
879
883
|
e.wrapperClassName,
|
884
|
+
e.wrapperProps,
|
880
885
|
(function(e, t) {
|
881
886
|
var r = {};
|
882
887
|
for (var n in e)
|
@@ -900,6 +905,7 @@ module.exports = (function(e) {
|
|
900
905
|
'useIntersectionObserver',
|
901
906
|
'visibleByDefault',
|
902
907
|
'wrapperClassName',
|
908
|
+
'wrapperProps',
|
903
909
|
]));
|
904
910
|
return i.default.createElement(
|
905
911
|
'img',
|
@@ -916,7 +922,7 @@ module.exports = (function(e) {
|
|
916
922
|
n = e.delayMethod,
|
917
923
|
o = e.delayTime,
|
918
924
|
a = e.height,
|
919
|
-
|
925
|
+
l = e.placeholder,
|
920
926
|
u = e.scrollPosition,
|
921
927
|
c = e.style,
|
922
928
|
f = e.threshold,
|
@@ -924,14 +930,14 @@ module.exports = (function(e) {
|
|
924
930
|
d = e.visibleByDefault,
|
925
931
|
y = e.width;
|
926
932
|
return i.default.createElement(
|
927
|
-
|
933
|
+
s.default,
|
928
934
|
{
|
929
935
|
beforeLoad: t,
|
930
936
|
className: r,
|
931
937
|
delayMethod: n,
|
932
938
|
delayTime: o,
|
933
939
|
height: a,
|
934
|
-
placeholder:
|
940
|
+
placeholder: l,
|
935
941
|
scrollPosition: u,
|
936
942
|
style: c,
|
937
943
|
threshold: f,
|
@@ -948,31 +954,35 @@ module.exports = (function(e) {
|
|
948
954
|
value: function(e) {
|
949
955
|
var t = this.props,
|
950
956
|
r = t.effect,
|
951
|
-
|
952
|
-
|
953
|
-
|
957
|
+
o = t.height,
|
958
|
+
a = t.placeholderSrc,
|
959
|
+
s = t.width,
|
954
960
|
l = t.wrapperClassName,
|
955
|
-
|
956
|
-
|
961
|
+
u = t.wrapperProps,
|
962
|
+
c = this.state.loaded,
|
963
|
+
f = c ? ' lazy-load-image-loaded' : '';
|
957
964
|
return i.default.createElement(
|
958
965
|
'span',
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
966
|
+
n(
|
967
|
+
{
|
968
|
+
className:
|
969
|
+
l +
|
970
|
+
' lazy-load-image-background ' +
|
971
|
+
r +
|
972
|
+
f,
|
973
|
+
style: {
|
974
|
+
backgroundImage:
|
975
|
+
c || !a ? '' : 'url(' + a + ')',
|
976
|
+
backgroundSize:
|
977
|
+
c || !a ? '' : '100% 100%',
|
978
|
+
color: 'transparent',
|
979
|
+
display: 'inline-block',
|
980
|
+
height: o,
|
981
|
+
width: s,
|
982
|
+
},
|
974
983
|
},
|
975
|
-
|
984
|
+
u
|
985
|
+
),
|
976
986
|
e
|
977
987
|
);
|
978
988
|
},
|
@@ -984,10 +994,12 @@ module.exports = (function(e) {
|
|
984
994
|
t = e.effect,
|
985
995
|
r = e.placeholderSrc,
|
986
996
|
n = e.visibleByDefault,
|
987
|
-
o =
|
988
|
-
|
989
|
-
|
990
|
-
|
997
|
+
o = e.wrapperClassName,
|
998
|
+
i = e.wrapperProps,
|
999
|
+
a = this.getLazyLoadImage();
|
1000
|
+
return ((t || r) && !n) || o || i
|
1001
|
+
? this.getWrappedLazyLoadImage(a)
|
1002
|
+
: a;
|
991
1003
|
},
|
992
1004
|
},
|
993
1005
|
]),
|
@@ -1005,6 +1017,7 @@ module.exports = (function(e) {
|
|
1005
1017
|
useIntersectionObserver: a.PropTypes.bool,
|
1006
1018
|
visibleByDefault: a.PropTypes.bool,
|
1007
1019
|
wrapperClassName: a.PropTypes.string,
|
1020
|
+
wrapperProps: a.PropTypes.object,
|
1008
1021
|
}),
|
1009
1022
|
(u.defaultProps = {
|
1010
1023
|
afterLoad: function() {
|
@@ -1033,10 +1046,10 @@ module.exports = (function(e) {
|
|
1033
1046
|
(e.exports = function() {
|
1034
1047
|
function e(e, t, r, o, i, a) {
|
1035
1048
|
if (a !== n) {
|
1036
|
-
var
|
1049
|
+
var s = new Error(
|
1037
1050
|
'Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types'
|
1038
1051
|
);
|
1039
|
-
throw ((
|
1052
|
+
throw ((s.name = 'Invariant Violation'), s);
|
1040
1053
|
}
|
1041
1054
|
}
|
1042
1055
|
function t() {
|
@@ -1089,13 +1102,13 @@ module.exports = (function(e) {
|
|
1089
1102
|
return r && e(t.prototype, r), n && e(t, n), t;
|
1090
1103
|
};
|
1091
1104
|
})(),
|
1092
|
-
o =
|
1093
|
-
i =
|
1094
|
-
a =
|
1095
|
-
function
|
1105
|
+
o = s(r(0)),
|
1106
|
+
i = s(r(4)),
|
1107
|
+
a = s(r(6));
|
1108
|
+
function s(e) {
|
1096
1109
|
return e && e.__esModule ? e : { default: e };
|
1097
1110
|
}
|
1098
|
-
var
|
1111
|
+
var l = (function(e) {
|
1099
1112
|
function t(e) {
|
1100
1113
|
return (
|
1101
1114
|
(function(e, t) {
|
@@ -1153,7 +1166,7 @@ module.exports = (function(e) {
|
|
1153
1166
|
t
|
1154
1167
|
);
|
1155
1168
|
})(o.default.Component);
|
1156
|
-
t.default = (0, a.default)(
|
1169
|
+
t.default = (0, a.default)(l);
|
1157
1170
|
},
|
1158
1171
|
function(e, t, r) {
|
1159
1172
|
(function(t) {
|
@@ -1162,8 +1175,8 @@ module.exports = (function(e) {
|
|
1162
1175
|
o = '[object Symbol]',
|
1163
1176
|
i = /^\s+|\s+$/g,
|
1164
1177
|
a = /^[-+]0x[0-9a-f]+$/i,
|
1165
|
-
|
1166
|
-
|
1178
|
+
s = /^0b[01]+$/i,
|
1179
|
+
l = /^0o[0-7]+$/i,
|
1167
1180
|
u = parseInt,
|
1168
1181
|
c = 'object' == typeof t && t && t.Object === Object && t,
|
1169
1182
|
f =
|
@@ -1202,8 +1215,8 @@ module.exports = (function(e) {
|
|
1202
1215
|
}
|
1203
1216
|
if ('string' != typeof e) return 0 === e ? e : +e;
|
1204
1217
|
e = e.replace(i, '');
|
1205
|
-
var r =
|
1206
|
-
return r ||
|
1218
|
+
var r = s.test(e);
|
1219
|
+
return r || l.test(e)
|
1207
1220
|
? u(e.slice(2), r ? 2 : 8)
|
1208
1221
|
: a.test(e)
|
1209
1222
|
? n
|
@@ -1213,27 +1226,27 @@ module.exports = (function(e) {
|
|
1213
1226
|
var o,
|
1214
1227
|
i,
|
1215
1228
|
a,
|
1216
|
-
l,
|
1217
1229
|
s,
|
1230
|
+
l,
|
1218
1231
|
u,
|
1219
1232
|
c = 0,
|
1220
1233
|
f = !1,
|
1221
1234
|
p = !1,
|
1222
1235
|
d = !0;
|
1223
1236
|
if ('function' != typeof e) throw new TypeError(r);
|
1224
|
-
function
|
1237
|
+
function w(t) {
|
1225
1238
|
var r = o,
|
1226
1239
|
n = i;
|
1227
|
-
return (o = i = void 0), (c = t), (
|
1240
|
+
return (o = i = void 0), (c = t), (s = e.apply(n, r));
|
1228
1241
|
}
|
1229
|
-
function
|
1242
|
+
function O(e) {
|
1230
1243
|
var r = e - u;
|
1231
1244
|
return void 0 === u || r >= t || r < 0 || (p && e - c >= a);
|
1232
1245
|
}
|
1233
1246
|
function g() {
|
1234
1247
|
var e = b();
|
1235
|
-
if (
|
1236
|
-
|
1248
|
+
if (O(e)) return P(e);
|
1249
|
+
l = setTimeout(
|
1237
1250
|
g,
|
1238
1251
|
(function(e) {
|
1239
1252
|
var r = t - (e - u);
|
@@ -1241,24 +1254,24 @@ module.exports = (function(e) {
|
|
1241
1254
|
})(e)
|
1242
1255
|
);
|
1243
1256
|
}
|
1244
|
-
function
|
1245
|
-
return (
|
1257
|
+
function P(e) {
|
1258
|
+
return (l = void 0), d && o ? w(e) : ((o = i = void 0), s);
|
1246
1259
|
}
|
1247
|
-
function
|
1260
|
+
function T() {
|
1248
1261
|
var e = b(),
|
1249
|
-
r =
|
1262
|
+
r = O(e);
|
1250
1263
|
if (((o = arguments), (i = this), (u = e), r)) {
|
1251
|
-
if (void 0 ===
|
1264
|
+
if (void 0 === l)
|
1252
1265
|
return (function(e) {
|
1253
1266
|
return (
|
1254
1267
|
(c = e),
|
1255
|
-
(
|
1256
|
-
f ?
|
1268
|
+
(l = setTimeout(g, t)),
|
1269
|
+
f ? w(e) : s
|
1257
1270
|
);
|
1258
1271
|
})(u);
|
1259
|
-
if (p) return (
|
1272
|
+
if (p) return (l = setTimeout(g, t)), w(u);
|
1260
1273
|
}
|
1261
|
-
return void 0 ===
|
1274
|
+
return void 0 === l && (l = setTimeout(g, t)), s;
|
1262
1275
|
}
|
1263
1276
|
return (
|
1264
1277
|
(t = m(t) || 0),
|
@@ -1268,15 +1281,15 @@ module.exports = (function(e) {
|
|
1268
1281
|
? y(m(n.maxWait) || 0, t)
|
1269
1282
|
: a),
|
1270
1283
|
(d = 'trailing' in n ? !!n.trailing : d)),
|
1271
|
-
(
|
1272
|
-
void 0 !==
|
1284
|
+
(T.cancel = function() {
|
1285
|
+
void 0 !== l && clearTimeout(l),
|
1273
1286
|
(c = 0),
|
1274
|
-
(o = u = i =
|
1287
|
+
(o = u = i = l = void 0);
|
1275
1288
|
}),
|
1276
|
-
(
|
1277
|
-
return void 0 ===
|
1289
|
+
(T.flush = function() {
|
1290
|
+
return void 0 === l ? s : P(b());
|
1278
1291
|
}),
|
1279
|
-
|
1292
|
+
T
|
1280
1293
|
);
|
1281
1294
|
};
|
1282
1295
|
}.call(this, r(7)));
|
@@ -1288,8 +1301,8 @@ module.exports = (function(e) {
|
|
1288
1301
|
o = '[object Symbol]',
|
1289
1302
|
i = /^\s+|\s+$/g,
|
1290
1303
|
a = /^[-+]0x[0-9a-f]+$/i,
|
1291
|
-
|
1292
|
-
|
1304
|
+
s = /^0b[01]+$/i,
|
1305
|
+
l = /^0o[0-7]+$/i,
|
1293
1306
|
u = parseInt,
|
1294
1307
|
c = 'object' == typeof t && t && t.Object === Object && t,
|
1295
1308
|
f =
|
@@ -1308,8 +1321,8 @@ module.exports = (function(e) {
|
|
1308
1321
|
var o,
|
1309
1322
|
i,
|
1310
1323
|
a,
|
1311
|
-
l,
|
1312
1324
|
s,
|
1325
|
+
l,
|
1313
1326
|
u,
|
1314
1327
|
c = 0,
|
1315
1328
|
f = !1,
|
@@ -1319,16 +1332,16 @@ module.exports = (function(e) {
|
|
1319
1332
|
function v(t) {
|
1320
1333
|
var r = o,
|
1321
1334
|
n = i;
|
1322
|
-
return (o = i = void 0), (c = t), (
|
1335
|
+
return (o = i = void 0), (c = t), (s = e.apply(n, r));
|
1323
1336
|
}
|
1324
|
-
function
|
1337
|
+
function O(e) {
|
1325
1338
|
var r = e - u;
|
1326
1339
|
return void 0 === u || r >= t || r < 0 || (p && e - c >= a);
|
1327
1340
|
}
|
1328
1341
|
function g() {
|
1329
1342
|
var e = b();
|
1330
|
-
if (
|
1331
|
-
|
1343
|
+
if (O(e)) return P(e);
|
1344
|
+
l = setTimeout(
|
1332
1345
|
g,
|
1333
1346
|
(function(e) {
|
1334
1347
|
var r = t - (e - u);
|
@@ -1336,49 +1349,49 @@ module.exports = (function(e) {
|
|
1336
1349
|
})(e)
|
1337
1350
|
);
|
1338
1351
|
}
|
1339
|
-
function
|
1340
|
-
return (
|
1352
|
+
function P(e) {
|
1353
|
+
return (l = void 0), d && o ? v(e) : ((o = i = void 0), s);
|
1341
1354
|
}
|
1342
|
-
function
|
1355
|
+
function T() {
|
1343
1356
|
var e = b(),
|
1344
|
-
r =
|
1357
|
+
r = O(e);
|
1345
1358
|
if (((o = arguments), (i = this), (u = e), r)) {
|
1346
|
-
if (void 0 ===
|
1359
|
+
if (void 0 === l)
|
1347
1360
|
return (function(e) {
|
1348
1361
|
return (
|
1349
1362
|
(c = e),
|
1350
|
-
(
|
1351
|
-
f ? v(e) :
|
1363
|
+
(l = setTimeout(g, t)),
|
1364
|
+
f ? v(e) : s
|
1352
1365
|
);
|
1353
1366
|
})(u);
|
1354
|
-
if (p) return (
|
1367
|
+
if (p) return (l = setTimeout(g, t)), v(u);
|
1355
1368
|
}
|
1356
|
-
return void 0 ===
|
1369
|
+
return void 0 === l && (l = setTimeout(g, t)), s;
|
1357
1370
|
}
|
1358
1371
|
return (
|
1359
|
-
(t =
|
1372
|
+
(t = w(t) || 0),
|
1360
1373
|
m(n) &&
|
1361
1374
|
((f = !!n.leading),
|
1362
1375
|
(a = (p = 'maxWait' in n)
|
1363
|
-
? y(
|
1376
|
+
? y(w(n.maxWait) || 0, t)
|
1364
1377
|
: a),
|
1365
1378
|
(d = 'trailing' in n ? !!n.trailing : d)),
|
1366
|
-
(
|
1367
|
-
void 0 !==
|
1379
|
+
(T.cancel = function() {
|
1380
|
+
void 0 !== l && clearTimeout(l),
|
1368
1381
|
(c = 0),
|
1369
|
-
(o = u = i =
|
1382
|
+
(o = u = i = l = void 0);
|
1370
1383
|
}),
|
1371
|
-
(
|
1372
|
-
return void 0 ===
|
1384
|
+
(T.flush = function() {
|
1385
|
+
return void 0 === l ? s : P(b());
|
1373
1386
|
}),
|
1374
|
-
|
1387
|
+
T
|
1375
1388
|
);
|
1376
1389
|
}
|
1377
1390
|
function m(e) {
|
1378
1391
|
var t = typeof e;
|
1379
1392
|
return !!e && ('object' == t || 'function' == t);
|
1380
1393
|
}
|
1381
|
-
function
|
1394
|
+
function w(e) {
|
1382
1395
|
if ('number' == typeof e) return e;
|
1383
1396
|
if (
|
1384
1397
|
(function(e) {
|
@@ -1398,8 +1411,8 @@ module.exports = (function(e) {
|
|
1398
1411
|
}
|
1399
1412
|
if ('string' != typeof e) return 0 === e ? e : +e;
|
1400
1413
|
e = e.replace(i, '');
|
1401
|
-
var r =
|
1402
|
-
return r ||
|
1414
|
+
var r = s.test(e);
|
1415
|
+
return r || l.test(e)
|
1403
1416
|
? u(e.slice(2), r ? 2 : 8)
|
1404
1417
|
: a.test(e)
|
1405
1418
|
? n
|
package/package.json
CHANGED
@@ -66,6 +66,7 @@ describe('LazyLoadComponent', function() {
|
|
66
66
|
isIntersectionObserverAvailable.mockImplementation(() => true);
|
67
67
|
window.IntersectionObserver = jest.fn(function() {
|
68
68
|
this.observe = jest.fn(); // eslint-disable-line babel/no-invalid-this
|
69
|
+
this.unobserve = jest.fn(); // eslint-disable-line babel/no-invalid-this
|
69
70
|
});
|
70
71
|
|
71
72
|
const lazyLoadComponent = mount(
|
@@ -93,6 +94,7 @@ describe('LazyLoadComponent', function() {
|
|
93
94
|
isIntersectionObserverAvailable.mockImplementation(() => true);
|
94
95
|
window.IntersectionObserver = jest.fn(function() {
|
95
96
|
this.observe = jest.fn(); // eslint-disable-line babel/no-invalid-this
|
97
|
+
this.unobserve = jest.fn(); // eslint-disable-line babel/no-invalid-this
|
96
98
|
});
|
97
99
|
|
98
100
|
const lazyLoadComponent = mount(
|
@@ -40,6 +40,7 @@ class LazyLoadImage extends React.Component {
|
|
40
40
|
useIntersectionObserver,
|
41
41
|
visibleByDefault,
|
42
42
|
wrapperClassName,
|
43
|
+
wrapperProps,
|
43
44
|
...imgProps
|
44
45
|
} = this.props;
|
45
46
|
|
@@ -89,6 +90,7 @@ class LazyLoadImage extends React.Component {
|
|
89
90
|
placeholderSrc,
|
90
91
|
width,
|
91
92
|
wrapperClassName,
|
93
|
+
wrapperProps,
|
92
94
|
} = this.props;
|
93
95
|
const { loaded } = this.state;
|
94
96
|
|
@@ -114,6 +116,7 @@ class LazyLoadImage extends React.Component {
|
|
114
116
|
height: height,
|
115
117
|
width: width,
|
116
118
|
}}
|
119
|
+
{...wrapperProps}
|
117
120
|
>
|
118
121
|
{lazyLoadImage}
|
119
122
|
</span>
|
@@ -121,11 +124,18 @@ class LazyLoadImage extends React.Component {
|
|
121
124
|
}
|
122
125
|
|
123
126
|
render() {
|
124
|
-
const {
|
127
|
+
const {
|
128
|
+
effect,
|
129
|
+
placeholderSrc,
|
130
|
+
visibleByDefault,
|
131
|
+
wrapperClassName,
|
132
|
+
wrapperProps,
|
133
|
+
} = this.props;
|
125
134
|
|
126
135
|
const lazyLoadImage = this.getLazyLoadImage();
|
136
|
+
const needsWrapper = (effect || placeholderSrc) && !visibleByDefault;
|
127
137
|
|
128
|
-
if (
|
138
|
+
if (!needsWrapper && !wrapperClassName && !wrapperProps) {
|
129
139
|
return lazyLoadImage;
|
130
140
|
}
|
131
141
|
|
@@ -144,6 +154,7 @@ LazyLoadImage.propTypes = {
|
|
144
154
|
useIntersectionObserver: PropTypes.bool,
|
145
155
|
visibleByDefault: PropTypes.bool,
|
146
156
|
wrapperClassName: PropTypes.string,
|
157
|
+
wrapperProps: PropTypes.object,
|
147
158
|
};
|
148
159
|
|
149
160
|
LazyLoadImage.defaultProps = {
|
@@ -3,64 +3,61 @@ import ReactDOM from 'react-dom';
|
|
3
3
|
import { PropTypes } from 'prop-types';
|
4
4
|
import isIntersectionObserverAvailable from '../utils/intersection-observer';
|
5
5
|
|
6
|
+
const checkIntersections = entries => {
|
7
|
+
entries.forEach(entry => {
|
8
|
+
if (entry.isIntersecting) {
|
9
|
+
entry.target.onVisible();
|
10
|
+
}
|
11
|
+
});
|
12
|
+
};
|
13
|
+
|
14
|
+
const LAZY_LOAD_OBSERVERS = {};
|
15
|
+
|
16
|
+
const getObserver = threshold => {
|
17
|
+
LAZY_LOAD_OBSERVERS[threshold] =
|
18
|
+
LAZY_LOAD_OBSERVERS[threshold] ||
|
19
|
+
new IntersectionObserver(checkIntersections, {
|
20
|
+
rootMargin: threshold + 'px',
|
21
|
+
});
|
22
|
+
|
23
|
+
return LAZY_LOAD_OBSERVERS[threshold];
|
24
|
+
};
|
25
|
+
|
6
26
|
class PlaceholderWithoutTracking extends React.Component {
|
7
27
|
constructor(props) {
|
8
28
|
super(props);
|
9
29
|
|
10
|
-
|
30
|
+
this.supportsObserver =
|
11
31
|
!props.scrollPosition &&
|
12
32
|
props.useIntersectionObserver &&
|
13
33
|
isIntersectionObserverAvailable();
|
14
34
|
|
15
|
-
this.
|
16
|
-
|
17
|
-
if (supportsObserver) {
|
35
|
+
if (this.supportsObserver) {
|
18
36
|
const { threshold } = props;
|
19
37
|
|
20
|
-
this.
|
21
|
-
this.checkIntersections,
|
22
|
-
{ rootMargin: threshold + 'px' }
|
23
|
-
);
|
38
|
+
this.observer = getObserver(threshold);
|
24
39
|
}
|
25
40
|
}
|
26
41
|
|
27
|
-
checkIntersections(entries) {
|
28
|
-
entries.forEach(entry => {
|
29
|
-
if (entry.isIntersecting) {
|
30
|
-
entry.target.onVisible();
|
31
|
-
}
|
32
|
-
});
|
33
|
-
}
|
34
|
-
|
35
42
|
componentDidMount() {
|
36
|
-
if (
|
37
|
-
this.placeholder &&
|
38
|
-
this.LAZY_LOAD_OBSERVER &&
|
39
|
-
this.LAZY_LOAD_OBSERVER.observer
|
40
|
-
) {
|
43
|
+
if (this.placeholder && this.observer) {
|
41
44
|
this.placeholder.onVisible = this.props.onVisible;
|
42
|
-
this.
|
45
|
+
this.observer.observe(this.placeholder);
|
43
46
|
}
|
44
47
|
|
45
|
-
if (
|
46
|
-
this.LAZY_LOAD_OBSERVER &&
|
47
|
-
!this.LAZY_LOAD_OBSERVER.supportsObserver
|
48
|
-
) {
|
48
|
+
if (!this.supportsObserver) {
|
49
49
|
this.updateVisibility();
|
50
50
|
}
|
51
51
|
}
|
52
52
|
|
53
|
-
|
54
|
-
if (this.
|
55
|
-
this.
|
53
|
+
componentWillUnmount() {
|
54
|
+
if (this.observer) {
|
55
|
+
this.observer.unobserve(this.placeholder);
|
56
56
|
}
|
57
57
|
}
|
58
58
|
|
59
59
|
componentDidUpdate() {
|
60
|
-
if (
|
61
|
-
this.LAZY_LOAD_OBSERVER &&
|
62
|
-
!this.LAZY_LOAD_OBSERVER.supportsObserver
|
63
|
-
) {
|
60
|
+
if (!this.supportsObserver) {
|
64
61
|
this.updateVisibility();
|
65
62
|
}
|
66
63
|
}
|
@@ -118,11 +115,24 @@ class PlaceholderWithoutTracking extends React.Component {
|
|
118
115
|
});
|
119
116
|
}
|
120
117
|
|
118
|
+
const styleProp = {
|
119
|
+
display: 'inline-block',
|
120
|
+
...style,
|
121
|
+
};
|
122
|
+
|
123
|
+
if (typeof width !== 'undefined') {
|
124
|
+
styleProp.width = width;
|
125
|
+
}
|
126
|
+
|
127
|
+
if (typeof height !== 'undefined') {
|
128
|
+
styleProp.height = height;
|
129
|
+
}
|
130
|
+
|
121
131
|
return (
|
122
132
|
<span
|
123
133
|
className={className}
|
124
134
|
ref={el => (this.placeholder = el)}
|
125
|
-
style={
|
135
|
+
style={styleProp}
|
126
136
|
>
|
127
137
|
{placeholder}
|
128
138
|
</span>
|
@@ -133,7 +143,7 @@ class PlaceholderWithoutTracking extends React.Component {
|
|
133
143
|
PlaceholderWithoutTracking.propTypes = {
|
134
144
|
onVisible: PropTypes.func.isRequired,
|
135
145
|
className: PropTypes.string,
|
136
|
-
height: PropTypes.number,
|
146
|
+
height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
137
147
|
placeholder: PropTypes.element,
|
138
148
|
threshold: PropTypes.number,
|
139
149
|
useIntersectionObserver: PropTypes.bool,
|
@@ -141,16 +151,14 @@ PlaceholderWithoutTracking.propTypes = {
|
|
141
151
|
x: PropTypes.number.isRequired,
|
142
152
|
y: PropTypes.number.isRequired,
|
143
153
|
}),
|
144
|
-
width: PropTypes.number,
|
154
|
+
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
145
155
|
};
|
146
156
|
|
147
157
|
PlaceholderWithoutTracking.defaultProps = {
|
148
158
|
className: '',
|
149
|
-
height: 0,
|
150
159
|
placeholder: null,
|
151
160
|
threshold: 100,
|
152
161
|
useIntersectionObserver: true,
|
153
|
-
width: 0,
|
154
162
|
};
|
155
163
|
|
156
164
|
export default PlaceholderWithoutTracking;
|
@@ -197,6 +197,7 @@ describe('PlaceholderWithoutTracking', function() {
|
|
197
197
|
isIntersectionObserverAvailable.mockImplementation(() => true);
|
198
198
|
window.IntersectionObserver = jest.fn(function() {
|
199
199
|
this.observe = jest.fn(); // eslint-disable-line babel/no-invalid-this
|
200
|
+
this.unobserve = jest.fn(); // eslint-disable-line babel/no-invalid-this
|
200
201
|
});
|
201
202
|
const onVisible = jest.fn();
|
202
203
|
const component = renderPlaceholderWithoutTracking({
|
@@ -211,6 +212,7 @@ describe('PlaceholderWithoutTracking', function() {
|
|
211
212
|
isIntersectionObserverAvailable.mockImplementation(() => true);
|
212
213
|
window.IntersectionObserver = jest.fn(function() {
|
213
214
|
this.observe = jest.fn(); // eslint-disable-line babel/no-invalid-this
|
215
|
+
this.unobserve = jest.fn(); // eslint-disable-line babel/no-invalid-this
|
214
216
|
});
|
215
217
|
const offset = 100000;
|
216
218
|
const onVisible = jest.fn();
|