diff --git a/app.js b/app.js new file mode 100644 index 0000000..6bfb1e2 --- /dev/null +++ b/app.js @@ -0,0 +1,5 @@ +import LazyloadImage from './lazyload-image.js'; + +customElements.define('lazyload-image', LazyloadImage, { + extends: 'img' +}); diff --git a/index.html b/index.html index cca7470..f3f4a88 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,8 @@ lazyload-image - + + + diff --git a/lazyload-image.html b/lazyload-image.html deleted file mode 100644 index b28c19c..0000000 --- a/lazyload-image.html +++ /dev/null @@ -1,56 +0,0 @@ - diff --git a/lazyload-image.js b/lazyload-image.js new file mode 100644 index 0000000..f2a4f97 --- /dev/null +++ b/lazyload-image.js @@ -0,0 +1,84 @@ +export default class LazyloadImage extends HTMLImageElement { + static get FALLBACK_IMAGE() { + return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42gEFAPr/AP///wAI/AL+Sr4t6gAAAABJRU5ErkJggg=='; + } + + static get observedAttributes() { + return [ + 'offset' + ]; + } + + constructor(width, height) { + super(width, height); + + this.original = this.currentSrc || this.src; + this.src = LazyloadImage.FALLBACK_IMAGE; + this.onIntersect = this.onIntersect.bind(this); + } + + connectedCallback() { + this.observe(); + } + + disconnectedCallback() { + this.unobserve(); + } + + get offset() { + return this.getAttribute('offset'); + } + + set offset(value) { + this.setAttribute('offset', value); + } + + get observer() { + if (!this.intersectionObserver) { + this.intersectionObserver = new IntersectionObserver(this.onIntersect, { + rootMargin: this.offset + }); + } + + return this.intersectionObserver; + } + + observe() { + this.observer.observe(this); + } + + unobserve() { + this.observer.unobserve(this); + this.observer.disconnect(); + } + + onIntersect(entries) { + if (entries.length === 0) { + return; + } + + if (entries[0].intersectionRatio <= 0) { + return; + } + + this.addEventListener('load', () => { + this.unobserve(); + }); + + this.addEventListener('error', () => { + this.src = LazyloadImage.FALLBACK_IMAGE; + this.unobserve(); + }); + + this.src = this.original; + } + + attributeChangedCallback(name, oldValue, newValue) { + if (this.observer === null) { + return; + } + + this.unobserve(); + this.observe(); + } +} diff --git a/readme.md b/readme.md index 9dbccb2..4ce1b8d 100644 --- a/readme.md +++ b/readme.md @@ -20,21 +20,30 @@ $ bower install lazyload-image ## Usage -Load `lazyload-image.html` in your HTML. +Load `lazyload-image.js` in your JavaScript. -```html - +```javascript +import LazyloadImage from './lazyload-image.js'; + +customElements.define('lazyload-image', LazyloadImage, { + extends: 'img' +}); ``` Modify your `` elements such as following. ```html - + ``` ## Fallback -If a browser does not support `document.registerElement()`, images will be loaded as usual. +If a browser does not support `customElements.define()`, images will be loaded as usual. ## License