diff --git a/ionic/components.ts b/ionic/components.ts index 02968e5ae93..1e98043d86a 100644 --- a/ionic/components.ts +++ b/ionic/components.ts @@ -7,6 +7,7 @@ export * from './components/button/button' export * from './components/checkbox/checkbox' export * from './components/content/content' export * from './components/icon/icon' +export * from './components/img/img' export * from './components/infinite-scroll/infinite-scroll' export * from './components/infinite-scroll/infinite-scroll-content' export * from './components/input/input' diff --git a/ionic/components/img/img.ts b/ionic/components/img/img.ts index 94dbc23132c..c2b49f30c3e 100644 --- a/ionic/components/img/img.ts +++ b/ionic/components/img/img.ts @@ -1,5 +1,6 @@ -import {Component, Input, HostBinding, ViewChild, ElementRef, ViewEncapsulation} from 'angular2/core'; +import {Component, Input, ElementRef, ChangeDetectionStrategy, ViewEncapsulation, NgZone} from 'angular2/core'; +import {raf} from '../../util/dom'; import {isPresent} from '../../util/util'; import {Platform} from '../../platform/platform'; @@ -7,50 +8,85 @@ import {Platform} from '../../platform/platform'; @Component({ selector: 'ion-img', template: - '
' + - '' + - '
' + - '', + '
', + changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) export class Img { private _src: string = ''; - private _srcA: string = ''; - private _srcB: string = ''; - private _useA: boolean = true; + private _normalizeSrc: string = ''; + private _imgs: HTMLImageElement[] = []; private _w: string; private _h: string; private _enabled: boolean = true; - constructor(private _elementRef: ElementRef, private _platform: Platform) {} - - @ViewChild('imgA') private _imgA: ElementRef; - @ViewChild('imgB') private _imgB: ElementRef; + constructor(private _elementRef: ElementRef, private _platform: Platform, private _zone: NgZone) {} @Input() set src(val: string) { - val = (isPresent(val) ? val : ''); - - if (this._src !== val) { - this._src = val; - this._loaded = false; - this._srcA = this._srcB = ''; - this._useA = !this._useA; - this._update(); - } + let tmpImg = new Image(); + tmpImg.src = isPresent(val) ? val : ''; + + this._src = isPresent(val) ? val : ''; + this._normalizeSrc = tmpImg.src; + + this._update(); } private _update() { - if (this._enabled && this.isVisible()) { - if (this._useA) { - this._srcA = this._src; + if (this._enabled && this._src !== '' && this.isVisible()) { + // actively update the image + + for (var i = this._imgs.length - 1; i >= 0; i--) { + if (this._imgs[i].src === this._normalizeSrc) { + // this is the active image + if (this._imgs[i].complete) { + this._loaded(true); + } + + } else { + // no longer the active image + if (this._imgs[i].parentElement) { + this._imgs[i].parentElement.removeChild(this._imgs[i]); + } + this._imgs.splice(i, 1); + } + } + + if (!this._imgs.length) { + this._zone.runOutsideAngular(() => { + let img = new Image(); + img.style.width = this._w; + img.style.height = this._h; + + img.addEventListener('load', () => { + if (img.src === this._normalizeSrc) { + this._elementRef.nativeElement.appendChild(img); + raf(() => { + this._update(); + }); + } + }); + + img.src = this._src; + + this._imgs.push(img); + this._loaded(false); + }); + } - } else { - this._srcB = this._src; + } else { + // do not actively update the image + if (!this._imgs.some(img => img.src === this._normalizeSrc)) { + this._loaded(false); } } } + private _loaded(isLoaded: boolean) { + this._elementRef.nativeElement.classList[isLoaded ? 'add': 'remove']('img-loaded'); + } + enable(shouldEnable: boolean) { this._enabled = shouldEnable; this._update(); @@ -61,26 +97,6 @@ export class Img { return bounds.bottom > 0 && bounds.top < this._platform.height(); } - @HostBinding('class.img-loaded') - private _loaded: boolean = false; - - private _onLoad() { - this._loaded = this.isLoaded(); - } - - isLoaded() { - let imgEle: HTMLImageElement; - - if (this._useA && this._imgA) { - imgEle = this._imgA.nativeElement; - - } else if (this._imgB) { - imgEle = this._imgB.nativeElement; - - } - return (imgEle && imgEle.src !== '' && imgEle.complete); - } - @Input() set width(val: string | number) { this._w = (typeof val === 'number') ? val + 'px' : val;