src/components/lazy-img/lazy-img.tsx
tag | lazy-img |
styleUrl | lazy-img.css |
Properties |
Methods |
addIntersectionObserver |
addIntersectionObserver()
|
Defined in src/components/lazy-img/lazy-img.tsx:52
|
Returns :
void
|
componentDidLoad |
componentDidLoad()
|
Defined in src/components/lazy-img/lazy-img.tsx:29
|
Returns :
void
|
componentWillUpdate |
componentWillUpdate()
|
Defined in src/components/lazy-img/lazy-img.tsx:33
|
Returns :
void
|
handleImage |
handleImage()
|
Defined in src/components/lazy-img/lazy-img.tsx:40
|
Returns :
void
|
removeIntersectionObserver |
removeIntersectionObserver()
|
Defined in src/components/lazy-img/lazy-img.tsx:74
|
Returns :
void
|
render |
render()
|
Defined in src/components/lazy-img/lazy-img.tsx:81
|
Returns :
any
|
alt |
alt:
|
Type : string
|
Decorators :
@Prop()
|
Defined in src/components/lazy-img/lazy-img.tsx:21
|
el |
el:
|
Type : HTMLElement
|
Decorators :
@Element()
|
Defined in src/components/lazy-img/lazy-img.tsx:18
|
io |
io:
|
Type : IntersectionObserver
|
Defined in src/components/lazy-img/lazy-img.tsx:27
|
lazyImgloaded |
lazyImgloaded:
|
Type : EventEmitter<HTMLImageElement>
|
Decorators :
@Event()
|
Defined in src/components/lazy-img/lazy-img.tsx:25
|
oldSrc |
oldSrc:
|
Type : string
|
Decorators :
@State()
|
Defined in src/components/lazy-img/lazy-img.tsx:23
|
src |
src:
|
Type : string
|
Decorators :
@Prop()
|
Defined in src/components/lazy-img/lazy-img.tsx:20
|
import {Component, Element, Event, EventEmitter, Prop, State} from '@stencil/core';
/*
You can use this component to lazy load below the fold images to improve load time.
Below the fold images are images that are not seen by the user until they have started to scroll.
Instead of loading all these images up front before the user even sees them, which will eat up
network bandwith, we can use this component to put off loading these images until the user has
scrolled to where that image is in your PWA.
To use this component use the following markup: <lazy-img src={/path/to/img} alt={alt text for img}></lazy-img>
*/
@Component({
tag: 'lazy-img',
styleUrl: 'lazy-img.css'
})
export class LazyImg {
@Element() el: HTMLElement;
@Prop() src: string;
@Prop() alt: string;
@State() oldSrc: string;
@Event() lazyImgloaded: EventEmitter<HTMLImageElement>;
io: IntersectionObserver;
componentDidLoad() {
this.addIntersectionObserver();
}
componentWillUpdate() {
console.log('componentWillUpdate called', this.src, this.oldSrc);
if (this.src !== this.el.querySelector('img').getAttribute('data-src')) {
this.addIntersectionObserver();
}
}
handleImage() {
const image: HTMLImageElement = this.el.querySelector('img');
console.log(image.getAttribute('data-src'));
if (image.getAttribute('data-src')) {
image.setAttribute('src', image.getAttribute('data-src'));
image.onload = () => {
image.removeAttribute('data-src');
this.lazyImgloaded.emit(image);
};
}
}
addIntersectionObserver() {
if (!this.src) {
return;
}
if ('IntersectionObserver' in window) {
this.io = new IntersectionObserver((data: IntersectionObserverEntry[]) => {
// because there will only ever be one instance
// of the element we are observing
// we can just use data[0]
if (data[0].isIntersecting) {
this.handleImage();
this.removeIntersectionObserver();
}
})
this.io.observe(this.el.querySelector('img'));
} else {
// fall back to just loading the image for Safari and IE
this.handleImage();
}
}
removeIntersectionObserver() {
if (this.io) {
this.io.disconnect();
this.io = null;
}
}
render() {
return (
<img data-src={this.src} alt={this.alt}></img>
);
}
}