Skip to content

Commit c2c9e67

Browse files
joshwhatkApoorvSaxena
authored andcommitted
🎉 Add loaded callback (#86)
* 🎉 Add loaded callback * 📝 Add documentation * 🐛 Fix overwriting of markAsLoaded method `markAsLoaded` is required to run for the `isLoaded` method to be useful. Also added a negative test for when a custom `load` option is passed in. * 🚿 Remove commented out code
1 parent 4cb5593 commit c2c9e67

File tree

5 files changed

+81
-11
lines changed

5 files changed

+81
-11
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@ lozad('.lozad', {
112112
});
113113
```
114114

115+
If you would like to extend the `loaded` state of elements, you can add the loaded option:
116+
117+
> **Note**: The `"data-loaded"="true"` attribute is used by lozad to determine if an element has been previously loaded.
118+
```js
119+
lozad('.lozad', {
120+
loaded: function(el) {
121+
// Custom implementation on a loaded element
122+
el.classList.add('loaded');
123+
}
124+
});
125+
```
126+
115127
If you want to lazy load dynamically added elements:
116128

117129
```js

dist/lozad.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*! lozad.js - v1.2.0 - 2018-01-24
1+
/*! lozad.js - v1.2.0 - 2018-02-10
22
* https://github.com/ApoorvSaxena/lozad.js
33
* Copyright (c) 2018 Apoorv Saxena; Licensed MIT */
44

@@ -38,7 +38,8 @@ var defaultConfig = {
3838
if (element.getAttribute('data-background-image')) {
3939
element.style.backgroundImage = 'url(' + element.getAttribute('data-background-image') + ')';
4040
}
41-
}
41+
},
42+
loaded: function loaded() {}
4243
};
4344

4445
function markAsLoaded(element) {
@@ -49,7 +50,7 @@ var isLoaded = function isLoaded(element) {
4950
return element.getAttribute('data-loaded') === 'true';
5051
};
5152

52-
var onIntersection = function onIntersection(load) {
53+
var onIntersection = function onIntersection(load, loaded) {
5354
return function (entries, observer) {
5455
entries.forEach(function (entry) {
5556
if (entry.intersectionRatio > 0) {
@@ -58,6 +59,7 @@ var onIntersection = function onIntersection(load) {
5859
if (!isLoaded(entry.target)) {
5960
load(entry.target);
6061
markAsLoaded(entry.target);
62+
loaded(entry.target);
6163
}
6264
}
6365
});
@@ -81,12 +83,13 @@ var lozad = function () {
8183
var _defaultConfig$option = _extends({}, defaultConfig, options),
8284
rootMargin = _defaultConfig$option.rootMargin,
8385
threshold = _defaultConfig$option.threshold,
84-
load = _defaultConfig$option.load;
86+
load = _defaultConfig$option.load,
87+
loaded = _defaultConfig$option.loaded;
8588

8689
var observer = void 0;
8790

8891
if (window.IntersectionObserver) {
89-
observer = new IntersectionObserver(onIntersection(load), {
92+
observer = new IntersectionObserver(onIntersection(load, loaded), {
9093
rootMargin: rootMargin,
9194
threshold: threshold
9295
});
@@ -106,6 +109,7 @@ var lozad = function () {
106109
}
107110
load(elements[i]);
108111
markAsLoaded(elements[i]);
112+
loaded(elements[i]);
109113
}
110114
},
111115
triggerLoad: function triggerLoad(element) {
@@ -115,6 +119,7 @@ var lozad = function () {
115119

116120
load(element);
117121
markAsLoaded(element);
122+
loaded(element);
118123
}
119124
};
120125
};

dist/lozad.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lozad.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ const defaultConfig = {
2525
if (element.getAttribute('data-background-image')) {
2626
element.style.backgroundImage = `url(${element.getAttribute('data-background-image')})`
2727
}
28-
}
28+
},
29+
loaded() {}
2930
}
3031

3132
function markAsLoaded(element) {
@@ -34,14 +35,15 @@ function markAsLoaded(element) {
3435

3536
const isLoaded = element => element.getAttribute('data-loaded') === 'true'
3637

37-
const onIntersection = load => (entries, observer) => {
38+
const onIntersection = (load, loaded) => (entries, observer) => {
3839
entries.forEach(entry => {
3940
if (entry.intersectionRatio > 0) {
4041
observer.unobserve(entry.target)
4142

4243
if (!isLoaded(entry.target)) {
4344
load(entry.target)
4445
markAsLoaded(entry.target)
46+
loaded(entry.target)
4547
}
4648
}
4749
})
@@ -58,11 +60,11 @@ const getElements = selector => {
5860
}
5961

6062
export default function (selector = '.lozad', options = {}) {
61-
const {rootMargin, threshold, load} = {...defaultConfig, ...options}
63+
const {rootMargin, threshold, load, loaded} = {...defaultConfig, ...options}
6264
let observer
6365

6466
if (window.IntersectionObserver) {
65-
observer = new IntersectionObserver(onIntersection(load), {
67+
observer = new IntersectionObserver(onIntersection(load, loaded), {
6668
rootMargin,
6769
threshold
6870
})
@@ -82,6 +84,7 @@ export default function (selector = '.lozad', options = {}) {
8284
}
8385
load(elements[i])
8486
markAsLoaded(elements[i])
87+
loaded(elements[i])
8588
}
8689
},
8790
triggerLoad(element) {
@@ -91,6 +94,7 @@ export default function (selector = '.lozad', options = {}) {
9194

9295
load(element)
9396
markAsLoaded(element)
97+
loaded(element)
9498
}
9599
}
96100
}

test/index.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,55 @@ describe('lozad', () => {
162162
})
163163
})
164164

165+
describe('when passing options', () => {
166+
beforeEach(() => {
167+
document.body.innerHTML = ''
168+
const image = document.createElement('img')
169+
image.dataset.src = Math.random()
170+
.toString(36)
171+
.substring(7)
172+
document.body.appendChild(image)
173+
})
174+
175+
it('should not load elements by default when custom load option is passed in', () => {
176+
const observer = lozad('.lozad', {
177+
load(element) {
178+
element.classList.add('loaded')
179+
}
180+
})
181+
const image = document.getElementsByTagName('img')[0]
182+
image.setAttribute('class', 'lozad')
183+
observer.observe()
184+
assert.equal(true, image.classList.contains('loaded'))
185+
assert.equal(null, image.getAttribute('src'))
186+
})
187+
188+
it('should run loaded option after loading an element', () => {
189+
const observer = lozad('.lozad', {
190+
loaded(element) {
191+
element.classList.add('loaded')
192+
}
193+
})
194+
const image = document.getElementsByTagName('img')[0]
195+
image.setAttribute('class', 'lozad')
196+
observer.observe()
197+
assert.equal(true, image.classList.contains('loaded'))
198+
})
199+
200+
it('should set data attribute when loaded option is passed in', () => {
201+
const observer = lozad('.lozad', {
202+
loaded(element) {
203+
element.classList.add('loaded')
204+
}
205+
})
206+
const image = document.getElementsByTagName('img')[0]
207+
image.setAttribute('class', 'lozad')
208+
observer.observe()
209+
assert.equal(true, image.classList.contains('loaded'))
210+
assert.equal('true', image.dataset.loaded)
211+
})
212+
})
213+
165214
describe('public API functions', () => {
166215
beforeEach(() => {
167216
document.body.innerHTML = ''

0 commit comments

Comments
 (0)