加载图片时显示加载动画

14

我写了一些代码,让用户可以上传一个ZIP文件中的一些图片。在下一个页面上,我需要将所有图像分别显示在一个85*85像素的框架中。

问题是加载所有图片可能需要一些时间。因此,我想在用户等待图片加载时显示一个加载gif。

我将图像的src设置为“加载gif”,同时创建了一些带有真实源ID的复选框。

echo "<td><img src=\"beelden/ajax-loader-black-16.png\" id=\"img".$image."\" style=\" width: 85px; height: 85px; border: 1px solid gray; background-color: #fff; padding: 10px;\">";
echo "<input type=\"checkbox\" id=\"img[".$image."]\" name=\"check_image[]\" value=\"".$filename."\" /></td>";
<input type="hidden" name="aantal" id="aantal" value="<?=$image?>" >

然后我创建了一些JavaScript代码来检查图像是否已加载,当图像已加载时,它应该替换图像的源。

<script>
    var aantal = document.getElementById("aantal").value;
    for(var i = 0; i < aantal; i++){
        var source = document.getElementById("img["+i+"]").value;
        var img = new Image();
        img.onload = function(){
            $("#img"+i).attr('src', source);
        }();
        img.src = source;
    }
</script>

但是它不像我预期的那样工作,我认为只要第一个图片加载完就会对所有图片触发。是否有任何想法我做错了什么或如何修复这个问题?


你如何调用你的 JavaScript 函数? - Saty
4
闭包下循环变量的经典案例。 - Amadan
1
创建一个Fiddle用于快速编辑和演示。 - codesnooker
дҪ иғҪеҲӣе»әдёҖдёӘfiddleжҲ–plunkerеҗ—пјҹдҪ еҶҷзҡ„document.getElementById("img["+i+"]").value;е’Ң$("#img"+i).еӨӘд»Өдәәеӣ°жғ‘дәҶгҖӮ - Bellash
哦,还有一件事我甚至没有注意到——函数会立即执行(见末尾的()),而img.onload被赋予了退出值——也就是undefined。闭合循环变量甚至没有时间成为一个错误。 - Amadan
显示剩余2条评论
2个回答

51

你可以通过CSS技巧将图像的背景设置为加载动画GIF。这是一个简单的方法,无需编写JavaScript脚本。

.loading {
  background: transparent url('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif') center no-repeat;
}
<img class="loading" src="http://placehold.it/106&text=1" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=2" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=3" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=4" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=5" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=6" width="106px" height="106px" />
<img class="loading" src="http://placehold.it/106&text=7" width="106px" height="106px" />

更新:

如果您有透明图片,那么情况会变得更加复杂,但仍然可以通过css和一些div元素来完成。

.image-wrapper {
  overflow: hidden;
  width: 106px;
  height: 106px;
  display: inline-block;
}

.image-wrapper img {
  float: left;
  display: block;
  opacity: 0.2; /* simulating a semitransparent image */
}

.image-wrapper:after, .loading {
  content: ' ';
  background: transparent url('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif')  center no-repeat ;
  background-size : auto 100%;
  width: 106px;
  height: 106px;
  float: left;
  display: block;
}
<div class="image-wrapper">
  <!-- simulates a hard loading image -->
  <img src="http://placehold.it/not-existing" alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=2" alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=3" alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=4" alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=5"  alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=6"  alt="" />
</div>
<div class="image-wrapper">
  <img src="http://placehold.it/106x106&text=7"  alt="" />
</div>

很遗憾,浏览器在加载时会添加一个损坏的图标或?,这就是为什么图像包含一个空的alt的原因;

更新2:

第二种变体非常依赖于图片大小,如果您有不同的大小,则加载gif将无法正确推开,作为替代方案,可以使用第一种变体和一个小的js脚本,该脚本会在图像加载完毕后立即删除背景:

$('img').load(function(){
   $(this).css('background','none');
});
   .loading {
      background: transparent url('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif') center no-repeat;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="loading" src="http://upload.wikimedia.org/wikipedia/en/2/2d/SRU-Logo-Transparent.png" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=2" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=3" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=4" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=5" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=6" width="106px" height="106px" />
    <img class="loading" src="http://placehold.it/106&text=7" width="106px" height="106px" />


如果原始图像也是透明的,这个能正常工作吗? - PirateSoul
1
不,它并没有按照我编写的那样。作为一种替代方案,您可以创建一些包装器/助手,在图像加载完成后将加载gif图标推开,我会更新我的答案。 - Tiberiu C.
我将接受这个作为可能的正确答案,我刚用JavaScript/jQuery修复了它,但我认为这是一个有效的替代方案 :) - PirateSoul
在哪个浏览器上? - Tiberiu C.
如果正在加载的图像是背景精灵,那该怎么办 (ಠ_ಠ) - dw1
对于精灵,它应该在第二次更新中进行一些修改后就可以工作了,但是有些人指出它并不起作用。 - Tiberiu C.

12

使用 Hostlistener 和 Hostbinding 的 Angular 8 解决方案。

1. 创建一个简单的属性指令

import { Directive, HostListener, Input, HostBinding } from '@angular/core';
@Directive({selector: '[imageLoader]'})
export class ImageLoaderDirective
{
  @Input('src') imageSrc;
  @HostListener('load')
  loadImage()
  {
  this.srcAttr=this.imageSrc;
  }

@HostBinding('attr.src') srcAttr="../../assets/pics/Loader.svg"
constructor() { }
}

基本上,我们将初始图像源设置为加载器图像。一旦图像加载完成(触发load事件),我们便监听它并将图像源设置为实际的图像。

2.现在您只需要在图像上使用所创建的属性即可。

<img imageLoader src='image.jpg'>

使用SVG不需要进行样式更改,而GIF可能需要进行CSS更改。

您可以访问网站以查看可工作的实现。


你能提供这个的完整指令代码吗?谢谢。 - fromage9747
@fromage9747 我已经在答案中更新了代码。如果有帮助,请点赞。 - Dragonknot
谢谢!我似乎找不到测试它是否工作的方法。即使在Chrome中将我的网络速度设置为缓慢的3G,它也不显示加载器。 - fromage9747
@fromage9747 这可能与您尝试显示的图像大小有关,但我不确定。作为参考,我有这个网站-https://valleyviewhomestays.firebaseapp.com。对于我来说,加载器显示出来了(但我的图像jpg是以MB为单位的)。我建议您使用分辨率和大小更高的图像应用加载器进行测试。 - Dragonknot
尽管问题并没有明确要求使用Angular解决方案,但我很高兴在这里找到了一个。我认为你的答案是解决该问题的Angular方法的良好基础。谢谢! - David Brem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接