等待背景图片(CSS)加载完成

10
假设我们有一个图片幻灯片,这些图片的缩略图以滑块的形式显示在 div 容器中(我用 Jquery 创建了),每个图片都包含在一个带有 CSS 背景设置的 <li> 中,当然代表着该图片。由于它们的大小和宽高比各不相同,我选择使用背景图片进行布局。
这些图片来自数据库,并且是动态创建的。 我的需求是: 在每个 <li> 上显示一个“正在加载”的消息,并等待背景图片被缓存后显示出来。他们所能想到的方法(并不确定是否可行)是:
  • 在显示“正在加载”消息时暂时取消每个 <li> 的背景
  • 为每个背景制作循环以获取图像 url
  • 使用 $.get 函数加载它,然后在加载完成后执行任何操作
除了可行的事情之外,这意味着它们将按顺序加载,因此如果某个图片由于某种原因无法加载,则脚本永远不会继续!
我看过一些网站使用 JS 仅在浏览器可见时加载图像,也许这可以是我寻找的相同情况,因为我正在使用滚动条,一次只显示部分图片,而当页面加载时。

你有没有考虑使用精灵图?这样你只需要将1个图像加载到DOM中,然后每个图像都从其中切片,会使生活更简单。只需在精灵图的onload事件中加载CSS表,并为所有元素显示加载器,直到CSS表加载完成即可。 - RobertPitt
不可能,图像来自数据库。 - Sandro Antonucci
5个回答

8

嗯,如果您只使用img标签,事情可能会更简单,但如果您确实想使用背景图像,则我只能想出一个解决方法。

诀窍是创建一个新图像(使用Javascript图像对象),并确保它已加载,但此图像不会显示。一旦图像加载并在缓存中,该图像将作为您的画廊的背景图像可用。

因此,您需要确保在相应的图像加载后才更改图片的LI的背景图像。您可以最初使用默认的“加载”图像加载所有LIs。

因此,您的代码应如下所示:

HTML(加载图像的style定义可以在外部样式表中):

<ul>
<li id="pic1" style="background-image:url('images/loading.gif')"></li>
<li id="pic2" style="background-image:url('images/loading.gif')"></li>
<li id="pic3" style="background-image:url('images/loading.gif')"></li>
...
</ul>

你的jQuery / Javascript代码:
var img = new Array();

// The following would be in some sort of loop or array iterator:

var num = [NUMBER] // You'd use this number to keep track of multiple images.
  // You could also do this by using $("ul>li").each() and using the index #

img[num] = new Image();

  // Specify the source for the image
var imgSource = "http://yourimage.com/example.jpg";

  // only append the corresponding LI after the image is loaded
img[num].onload = function() {
    $("#pic" + num).attr("style", "background-image:url('" + imgSource + "')");
};

img[num].src = imgSource;​

你需要为每个 LI 添加适当的 CSS / ids 等,同时你需要根据你用来展示画廊的循环或函数进行适应。这里有一个 jsFiddle 示例(点击查看)。 (为了测试目的,它是一张大图,所以加载时间会比较长)。

我想我明白你的意思了。 问题是我的图像被设置为内联样式代码中的背景,就像这样:<li style="background: url('/media/images_thumb/daniel/6.jpg') center no-repeat"></li> 所以我需要先将所有图像都转换为对象,然后再为每个li设置背景?我能在Jquery中获取背景吗? - Sandro Antonucci
@Sandro - 没关系,只需要使用一个变量来设置每个LI的图像源和背景图像。就像这样 ==> http://jsfiddle.net/aDDkZ/ - 编辑答案以反映更改。 - Peter Ajtai
嗨,我想我知道如何从li中获取css值以了解img的url,但这是否意味着我必须等待所有图像加载完成或仅按顺序加载每个图像?我想在单独加载每个图像时立即显示它们。 - Sandro Antonucci
@Sandro - 不需要,但你需要使用数组或多个img变量。我稍微修改了代码以展示如何处理多张图片。 - Peter Ajtai

2
你可以使用CSS技巧而不是一些冗长的JavaScript代码。你可以像这样做:
HTML:
<ul id="slideshow-container">
  <li><div id="image1"></div></li>
  <li><div id="image2"></div></li>
  <li><div id="image3"></div></li>
  <li><div id="image4"></div></li>
</ul>

CSS:

#slideshow-container>li{
  background-image:url('loading.gif')
}

#slideshow-container>li>div{
  width:100%;
  height:100%;
}

#slideshow-container>li>div{
  background-color:transparent;
}

#image1{
  background-image:url('image1.jpg');
}

#image2{
  background-image:url('image2.jpg');
}

#image3{
  background-image:url('image3.jpg');
}

#image4{
  background-image:url('image4.jpg');
}


解释:
幻灯片的图片将成为li包含的div的背景。 在图片加载之前,背景将是透明的,这将显示li的背景,即动画加载gif。
简单来说,li的加载图像将显示,直到包含在div中的幻灯片图像被加载。


0

嗯,我认为你可能把事情搞得太复杂了。我不太确定为什么你要使用CSS背景,而图片可以放在标签内部。你说的原因是因为你的图片是动态创建的...我不理解。

你可以做的是创建一个返回图像的页面,也许你可以使用一些参数...比如图像大小:

http://www.mysite.com/create_image.php?size=200x100&id=img1

那么你需要做的就是将此URL放入img标记的SRC中...如果你想的话,可以在页面加载时预加载图像...或者当你的滑块移动时

或者我可能没有理解你的问题 =D


1
因为它们都具有不同的大小和纵横比,所以使用背景会变得混乱。有些图片大小为100x800像素,因此使用背景确实会截掉一部分,但同时也会给出一个固定的大小。 - Sandro Antonucci
是的,我看了那部分...这就是为什么你可以将大小作为参数传递,看看这个..我为一个网站制作了这个http://jleanoma.perso.info.unicaen.fr/feed-bee/helpers/images.php?size=large&urlImage=http://www.google.com/intl/en_ALL/images/logos/images_logo_lg.gif你可以更改urlImage并且还可以指定大小(小或大)。在代码内部,我动态调整图像大小,始终保持纵横比,结果始终是相同的大小。 将该URL放入img标签中即可完成。 - pleasedontbelong

0

我使用的解决方案是有两层元素。

一层是一个带有背景加载符号的盒子。这个符号总是可见的。然后在上面的第二层中,我放置了带有图像的元素,并使用jQuery的.ready()函数和.delay()以及.fade()方法。

因为这很复杂,所以我来展示一下我的做法:

    <!-- Page Elements -->

    <div id="background-loading"> // Background image of spinner
      <div id="slider-case"> // Container of slider
        <ul id="slider-content">
          <li class="slider-image"></li>
          <li class="slider-image"></li>
          <li class="slider-image"></li>
        </ul>
      </div>
    </div>

    <!-- Script -->

  // Somewhere you have a script that manages the slider
  // Below is the loading animation/image manager
  $(document).ready(function() {
    $('#slider-content').delay(200).animate({opacity:1.0}, 'linear', function(){ 
      $('#background-loading').animate({opacity:0, 'margin-left':'-70px'}, 'linear');
      $('.slider-image').animate({opacity:1.0, 'margin-left':'0em'}, 'linear', function(){});
    });
  });

延迟和淡入使载入时间看起来是有意为之,而.ready()将等待元素完全加载。
通过拥有单独的背景层,您无需担心除滑块外的任何操作。要添加其他效果,可以回调图像加载,执行到加载动画的淡入。

0
它会查找具有src属性或backgroundImage CSS属性的元素,并在它们的图像加载完成时调用一个动作函数。
/**
 * Load and wait for loading images.
 */
function loadImages(images, action){
    var loaded_images = 0;
    var bad_tags = 0;        

    $(images).each(function() {
    //alert($(this).get(0).tagName+" "+$(this).attr("id")+" "+$(this).css("display"));
        var image = new Image();
        var src = $(this).attr("src");
        var backgroundImage = $(this).css("backgroundImage");            
        // Search for css background style
        if(src == undefined && backgroundImage != "none"){
            var pattern = /url\("{0,1}([^"]*)"{0,1}\)/;                
            src = pattern.exec(backgroundImage)[1];                
        }else{
            bad_tags++;
        }
        // Load images
        $(image).load(function() {
            loaded_images++;                
            if(loaded_images == ($(images).length - bad_tags))
                action();
        })
        .attr("src", src);
    });
}

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