2016-09-23 96 views
10

我有这个角度项目,我有一个大的背景图片,填充页面和一个简单的边栏,点击链接后,将改变另一个图像(从CDN)的背景的网址。由于这些图像相当大,他们需要一两个或两个加载,这是显而易见的,我想添加一个预加载程序,但我不知道这将如何做角2。Angular 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'; 
} 

所以URL实际上是在改变立即但图像需要加载一点。我想添加一个加载gif或类似的东西,以保持图像更改顺利的用户,而不是像现在这样跳动。

回答

12

一种方式做到这一点是使用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()); 
     }); 
    } 
} 

NB:您应该输入您的数据参数,打字是确保您的代码一致性的好方法,any只能用作小丑,如ObjectJava

+0

我要去尝试,但它会打破我的CSS使背景的大小是封面,我不知道如何做到这一点,我一直使用jQuery的。 –

+0

你应该寻找CSS让img成为一个固定的背景,因为实现你想要的东西的唯一方法就是用这种方式来做,使用blob。 – Supamiu

+0

好吧,这比背景问题更重要,我会看到我如何排序,将尝试你的方法 –

7

使用图像对象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

该解决方案利用什么角度和浏览器已经提供。图像加载是由浏览器完成的,不需要自己弄乱任何数据或DOM。

我已经在Chrome 53上测试过它,它的工作完美无瑕。

这是你的元素,那就是获取其背景变了:

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

预取的图像中,我们使用图像标签,未显示。另外制作它的position: absolute并将它移出视图或使它变得非常小,这样它就不会干扰你的实际内容。

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

通过设置imgPreloadUrl,所述imgsrc由角更新,浏览器将图像加载到无形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>