2016-09-23 27 views
10

Tôi có dự án góc cạnh này, nơi tôi có một hình nền lớn lấp đầy trang và một thanh bên đơn giản với các liên kết mà khi được nhấp, sẽ thay đổi url của nền bằng một hình ảnh khác (từ cdn). Vì những hình ảnh này khá lớn nên phải mất một hoặc hai giây để tải và đáng chú ý, tôi muốn thêm trình tải trước nhưng tôi không chắc chắn cách thực hiện điều đó trong góc 2.Góc 2 - Tải trước hình nền?

Trong html của tôi, tôi có:

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

các urlImage biến được phổ biến trong các nhà xây dựng của các thành phần và các liên kết sidebar thay đổi giá trị của nó trên nhấp chuột với một chức năng đơn giản giống như vậy:

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

So url được trên thực tế đã thay đổi ngay lập tức nhưng hình ảnh mất một chút để tải. Tôi muốn thêm một gif tải hoặc một cái gì đó như thế để giữ cho hình ảnh thay đổi trơn tru cho người sử dụng và không phải nhảy như bây giờ.

Trả lời

12

Một cách để làm điều đó sẽ được sử dụng Blob để có được những hình ảnh và lưu nó trong một thành phần img, bằng cách này bạn có bàn tay của bạn trên quá trình tải và bạn có thể thêm gif tải của bạn:

@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()); 
     }); 
    } 
} 

NB: Bạn nên nhập thông số dữ liệu của mình, nhập là cách tốt để đảm bảo tính nhất quán trên mã của bạn, chỉ sử dụng any làm joker, như Object trong Java.

+0

Tôi sẽ cố gắng đó, nhưng nó sẽ phá vỡ css của tôi để làm cho kích thước nền được bao gồm, tôi không chắc chắn làm thế nào để làm điều đó trong góc cạnh, tôi đã luôn luôn sử dụng jquery cho điều đó. –

+0

bạn nên tìm kiếm css để biến img thành nền cố định, bởi vì cách duy nhất để đạt được những gì bạn muốn là làm theo cách này, sử dụng blob. – Supamiu

+0

Ok, điều này quan trọng hơn vấn đề nền, tôi sẽ xem cách tôi sắp xếp, sẽ thử cách tiếp cận của bạn –

7

Sử dụng hình ảnh đối tượng (Plunker Demo)

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'; 
} 
7

Giải pháp này thúc đẩy những gì góc và trình duyệt đã cung cấp. Việc tải hình ảnh được thực hiện bởi trình duyệt và không cần phải gây rối với bất kỳ dữ liệu hoặc bản thân DOM nào.

Tôi đã thử nghiệm điều này trên Chrome 53 và nó hoạt động hoàn hảo.

Đây là yếu tố của bạn, đó là nhận được nền của nó thay đổi:

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

Để prefetch hình ảnh, chúng tôi sử dụng một thẻ hình ảnh, đó là không được hiển thị. Nó sẽ là tốt để bổ sung làm cho nó position: absolute và di chuyển nó ra khỏi tầm nhìn hoặc làm cho nó thực sự nhỏ, để nó không thể can thiệp với nội dung thực tế của bạn.

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

Qua thiết imgPreloadUrl, các 's imgsrc được cập nhật bởi góc và trình duyệt sẽ tải hình ảnh vào img thẻ vô hình. Sau khi hoàn tất, onload cháy và chúng tôi đặt imgUrl = imgPreloadUrl. Angular hiện cập nhật style.background-image của nền thực tế và hình nền chuyển ngay lập tức vì nó đã được tải trong hình ảnh ẩn.

Trong khi imgUrl !== imgPreloadUrl chúng tôi có thể hiển thị một spinner để chỉ tải:

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

thử nghiệm với:

<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> 
Các vấn đề liên quan