簡體   English   中英

Angular 2 - 預加載背景圖片?

[英]Angular 2 - Preload background image?

我有這個角度項目,我有一個填充頁面的大背景圖像和一個帶有鏈接的簡單側邊欄,點擊后,將用另一個圖像(來自cdn)更改背景的URL。 由於這些圖像相當大,它們需要一兩秒才能加載並且它很明顯,我想添加一個預加載器,但我不確定如何在角度2中完成。

在我的HTML中我有這個:

<section class="fullsizebg image-bg" [ngStyle]="{'background-image': 'url(' + urlImage + ')'}"></section>

變量urlImage填充在組件的構造函數中,側邊欄鏈接在單擊時更改它的值,使用一個簡單的函數,如下所示:

generateImage(data: any){
    this.urlImage = 'http://example.com/mycdn/'+this.data.url+'.jpg';
}

因此,網址實際上會立即更改,但圖像需要加載一些。 我想添加一個加載gif或類似的東西,以保持圖像變化順利給用戶,而不是像現在一樣跳躍。

一種方法是使用Blob獲取圖像並將其存儲在img組件中,這樣您就可以完成加載過程了,並且可以添加加載gif:

@Component({
   selector:'loading-image',
   template:'<img alt="foo" [src]="src"/>'
})
export class ExampleLoadingImage{

   public src:string = "http://example.com/yourInitialImage.png";

   constructor(private http:Http){}

   generateImage(data: any): void {
      this.src = 'http://www.downgraf.com/wp-content/uploads/2014/09/01-progress.gif'; //Just a random loading gif found on google.
      this.http.get('http://example.com/mycdn/'+this.data.url+'.jpg')
         .subscribe(response => {
            let urlCreator = window.URL;
            this.src = urlCreator.createObjectURL(response.blob());
         });
    }
}

注意 :你應該鍵入你的數據參數,鍵入是確保代碼一致性的好方法, any只應該用作joker,比如Java Object

該解決方案利用了角度和瀏覽器已經提供的角度。 圖像加載由瀏覽器完成,無需自己處理任何數據或DOM。

我已經在Chrome 53上對它進行了測試,它運行良好。

這是你的元素,它的背景改變了:

<div class="yourBackgroundClass" [style.background-image]="'url(' + imgUrl + ')'"></div>

要預取圖像,我們使用未顯示的圖像標記。 最好另外確定它的position: absolute並將其移出視圖或使其非常小,這樣它就不會干擾您的實際內容。

<img [src]="imgPreloadUrl" (load)="imgUrl = imgPreloadUrl" hidden>

通過設置imgPreloadUrlimgsrc按角度更新,瀏覽器將圖像加載到不可見的img標簽中。 一旦完成, onload觸發,我們設置imgUrl = imgPreloadUrl Angular現在更新了實際背景的style.background-image ,並且背景圖像立即切換,因為它已經加載到隱藏圖像中。

imgUrl !== imgPreloadUrl我們可以顯示一個微調器來指示加載:

<div class="spinner" *ngIf="imgUrl !== imgPreloadUrl"></div>

測試:

<button (click)="imgPreloadUrl = 'https://upload.wikimedia.org/wikipedia/commons/2/24/Willaerts_Adam_The_Embarkation_of_the_Elector_Palantine_Oil_Canvas-huge.jpg'">test</button>

使用圖像對象Plunker演示

tmpImg: HTMLImageElement; // will be used to load the actual image before showing it

generateImage(data: any){
 this.urlImage = 'http://example.com/mycdn/'+ 'loading_GIF_url';  // show loading gif

 let loaded = () => { // wait for image to load then replace it with loadingGIF
   this.urlImage = 'http://example.com/mycdn/' + this.data.url+'.jpg';
 }

 // background loading logic
 if(this.tmpImg){
   this.tmpImg.onload = null; // remove the previous onload event, if registered
 }
 this.tmpImg = new Image();
 this.tmpImg.onload = loaded;  // register the onload event
 this.tmpImg.src = 'http://example.com/mycdn/'+this.data.url+'.jpg';
}

你需要的東西很少,如http,解析器和消毒劑。 這是一個解釋如何從頭開始實現它的鏈接

因此,例如,您有一個請求,然后將返回的blob轉換為安全樣式,以便我們能夠在style指令中使用它

this.http.get('assets/img/bg.jpg', { responseType: 'blob' }).pipe(
  map( image => {
    const blob: Blob = new Blob([image], { type: 'image/jpeg' });
    const imageStyle = `url(${window.URL.createObjectURL(blob)})`;
    return this.sanitizer.bypassSecurityTrustStyle(imageStyle);
  })
)

我最近將其作為結構指令實現

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({ selector: '[appPreloadImage]'})
export class PreloadImageDirective {

  @Input("appPreloadImage") imageUrl : string;

  constructor( private templateRef : TemplateRef<any>,
               private viewContainer : ViewContainerRef) {
  }

  private showView() {
    this.viewContainer.createEmbeddedView(this.templateRef);
  }

  ngOnInit() {
    var self = this;
    self.viewContainer.clear();
    var tmpImg = new Image();
    tmpImg.src = self.imageUrl;
    tmpImg.onload = function() {
        self.showView();
    }
    tmpImg.onerror = function() {
        self.showView();
    }
  }
}

你可以像這樣使用它:

<div *appPreloadImage="'/url/of/preloaded/image.jpg'">
  <!-- Nothing in here will be displayed until the 
       request to the URL above has been completed 
      (even if that request fails) -->
</div>

(注意嵌套在雙引號內的單引號 - 這是因為我們傳遞的是字符串文字。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM