-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
109 lines (83 loc) · 2.41 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
var win = require( './util' ).win;
var _reduce = require( 'lodash-node/compat/collection/reduce' );
var _forEach = require( 'lodash-node/compat/collection/forEach' );
// Constants
var DEFAULTS = {
IMAGE_SEL: '.lazy-load',
ATTR_KEY: 'data-src'
};
// Cache
var bottomOffset = 0;
function getImages ( sel ) {
return win.document.querySelectorAll( sel );
}
function getOffset ( elem ) {
return elem.offsetTop;
}
function getBottomOffset () {
var scrollTop = win.document.body.scrollTop;
var viewPortHeight = win.innerHeight;
var newBottomOffset = scrollTop + viewPortHeight;
// If the user is scrolling upward, return undefined. This will
// result in a short circuit within the handleScroll method.
if ( newBottomOffset < bottomOffset ) {
return;
}
bottomOffset = newBottomOffset;
return newBottomOffset;
}
function getAttr ( elem, key ) {
return elem.getAttribute( key );
}
function getCacheStructure () {
return {
loaded: false,
elems: []
};
}
function mapOffsets ( elems ) {
return _reduce( elems, function ( obj, elem ) {
var offset = getOffset( elem );
if ( !obj.hasOwnProperty( offset ) ) {
obj[ offset ] = getCacheStructure();
}
obj[ offset ].elems.push( elem );
return obj;
}, {} );
}
function loadImages ( elems, attrKey ) {
_forEach( elems, function ( val ) {
var src = getAttr( val, attrKey );
if ( !src ) {
return false;
}
val.setAttribute( 'src', src );
});
}
function handleScroll ( imageOffsets, bottomOffset, attrKey ) {
if ( !bottomOffset ) {
return;
}
_forEach( imageOffsets, function ( val, key ) {
if ( !val.loaded && key <= bottomOffset ) {
loadImages( val.elems, attrKey );
val.loaded = true;
}
});
}
function bindScrollHandler ( imageOffsets, attrKey ) {
win.addEventListener( 'scroll', function () {
handleScroll( imageOffsets, getBottomOffset(), attrKey );
});
}
module.exports.init = function ( imageSel, attrKey ) {
imageSel = imageSel || DEFAULTS.IMAGE_SEL;
attrKey = attrKey || DEFAULTS.ATTR_KEY;
var images = getImages( imageSel );
if ( !images.length ) {
return;
}
var imageOffsets = mapOffsets( images );
bindScrollHandler( imageOffsets, attrKey );
return imageOffsets;
};