-
Notifications
You must be signed in to change notification settings - Fork 10
/
lazy-image.js
92 lines (80 loc) · 2.51 KB
/
lazy-image.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
/**
* <lazy-image> is a custom element that contains an image that has the
* option to be loaded only on-demand, for performance reasons.
*/
class LazyImage extends HTMLElement {
/**
* The constructor does work that needs to be executed _exactly_ once, such
* as initializing any private properties, or creating a shadow root (if the
* shadow DOM is used)
*/
constructor() {
super();
// Initialize the properties this element uses.
this._active = window.LazyImageSiteDefaultActive || false;
this._src = null;
this._srcset = null;
this._alt = null;
// Create an <img> element that will load the image on demand.
this._img = document.createElement('img');
this._img.style.width = '100%';
// Bubble up this load event.
this._img.addEventListener('load', function() {
var event = new Event('load');
event.detail = {originalTarget : this._img};
this.dispatchEvent(event);
}.bind(this))
}
connectedCallback() {
if (this.hasAttribute('as-decorator')) {
this.appendChild(this._img);
}
else {
// Add the <img> element inside the shadow root.
const shadow = this.attachShadow({mode: 'open'});
shadow.appendChild(this._img);
}
}
get active() { return this._active; }
set active(value) {
// Convert the value to a boolean correctly, since an empty string actually
// means "true" for boolean attributes.
this._active = (value !== null && value !== undefined) ? true : false;
if (this._src || this._srcset)
this._maybeLoadImage();
// Also set the attribute, because we want the option to use it for styling.
this.setAttribute('active', this._active);
}
get src() { return this._src; }
set src(value) {
this._src = value;
if (this._src)
this._maybeLoadImage();
}
get srcset() { return this._srcset; }
set srcset(value) {
this._srcset = value;
if (this._srcset)
this._maybeLoadImage();
}
get alt() { return this._img.alt; }
set alt(value) {
this._img.alt = value;
}
_maybeLoadImage() {
if (this._active) {
this._img.src = this._src || '';
this._img.srcset = this._srcset || '';
} else {
this._img.src = '';
this._img.srcset = '';
}
}
// Respond to attribute changes.
static get observedAttributes() { return ['active', 'src', 'srcset', 'alt']; }
attributeChangedCallback(attr, oldValue, newValue) {
if (oldValue !== newValue)
this[attr] = newValue;
}
}
window.customElements.define('lazy-image', LazyImage);