使用JS或CSS一次性加载所有背景图片?

3

我现在有一个设施列表,每个设施都有一个image属性,它只是它的图像文件名。例如,facility.image == 'YogisBarAndGrill'。在页面加载时,通过JSON发送了一组字符串(图像名称),并尝试在显示页面和/或文本之前加载所有图像。

不幸的是,我的所有努力都没有成功预加载图像。目前,在document.ready()之前执行以下操作:

(function() {
  var imagesPath, serviceURL, urlSegs;
  urlSegs = window.location.pathname.split("/");
  serviceURL = imagesPath = '';
  if (urlSegs.length === 2) {
    serviceURL = urlSegs[1] + '_images';
    imagesPath = urlSegs[1] === 'places' ? 'images/logos/' : 'images/categories/';
    $.getJSON(serviceURL, function(imageNames) {
      var i, _results;
      _results = [];
      for (i in imageNames) {
        if (i < imageNames.length) {
          _results.push((new Image()).src = imagesPath + imageNames[i] + '.png');
        }
      }
      return _results;
    });
  }
}).call(this);

每个列表图像的css如下所示:background-image: url('images/logos/YogisBarAndGrill.png')或类似内容。
无论如何 - 我上面发布的不起作用。没有预加载。我想要实现的是所有图像一次性显示,或者更好的是在所有图像加载完成之前不显示页面。
谢谢任何帮助!

2
如果我使用速度较慢的3G连接,想在加载完毕前开始阅读页面怎么办? - Matti Virkkunen
啊,我明白了。嗯,那没问题。现在发生的是,图像一个接一个地显示,因为它们正在下载(我认为每个都是单独的HTTP请求...但我希望不是)。我想在最后一个被下载后一次性显示所有图像 - 在那种情况下。 - Matt
2个回答

0
当你说预加载“不起作用”时,你是指什么?你期望发生什么?
“预加载”意味着“在需要之前加载”。如果具有这些背景图像的HTML元素与您使用的JavaScript位于同一页上,则浏览器将在解析CSS后立即下载它们,这很可能在JavaScript停止运行后不久就会发生。

啊,好的。所以,我试着在所有图片都下载完之前不显示它们,因为它们都需要立即显示。我猜预加载并不是正确的术语。 - Matt
@Matt: 哦!明白了。针对你在问题中的评论,每个图像确实是单独的HTTP请求,因为每个HTTP请求只能发送到一个地址,即每个图像的地址。唯一避免这种情况的方法是将所有图像合并为一个图像文件放在服务器上方便使用,并用其作为固定大小的HTML元素的背景图像,再利用背景定位来呈现图像文件的正确部分。这就是所谓的“雪碧图”。 - Paul D. Waite
@Matt:回答你的实际问题,雪碧图是一种只有在所有图片都下载完毕后才显示的方法。我不确定你是否还有其他选择——理论上,JavaScript 是解决这个问题的方法,但看起来 jQuery 尝试检测图片加载 的方式并不可靠,如果这样都不行,我对其他解决方案也不抱太大希望。 - Paul D. Waite
@Matt:或者,如果你可以在用户很可能在此页面之前访问过的页面上使用JavaScript技术预加载图像,那么它们可能会被浏览器缓存,因此当用户打开此页面时图片将立即显示。显然这对于直接进入此页面的用户无效。 - Paul D. Waite
在三分钟内向自己的答案添加三个评论应该真的能够获得一个徽章。 - Paul D. Waite

0
你可以通过动态创建每个要加载的图像的<img>元素,让它们完成加载,然后将background-image设置为相同的URL来实现这一点。在演示中,我每次运行都使用随机图像,因此它们不会被缓存。 演示:http://jsfiddle.net/ThinkingStiff/Mp2cj/

脚本:

function loadImages() {

    var images = getImages( 5 ),
        imgs = [],
        loaded = 0;

    createImgs();

    var timer = window.setInterval( function () {
        if( loaded == images.length ) {
            window.clearInterval( timer );
            setImages();
        };
    }, 50 );

    function createImgs() {
        for( var index = 0; index < images.length; index++ ) {
            imgs.push( document.createElement( 'img' ) );
            imgs[index].onload = function () { loaded++; };
            imgs[index].src = images[index];
        };
    };

    function setImages() {
        var divs = document.querySelectorAll( '#container div' );

        for( var index = 0; index < divs.length; index++ ) {
            divs[index].style.backgroundImage = 'url(' + images[index] + ')';
            console.log( 'div' );            
        };

        document.getElementById( 'container' ).removeAttribute( 'class' );
        document.getElementById( 'loading' ).setAttribute( 'class', 'hide' );
    };

    function getImages( count ) {
        var images = [],
            url = 'http://placekitten.com/';

        for( var index = 0, width, height; index < count; index++ ) {
            width = Math.floor( Math.random() * ( 1000 - 500 + 1 ) ) + 500;
            height = Math.floor( Math.random() * ( 1000 - 500 + 1 ) ) + 500;
            images.push( url + width + '/' + height );
        };

        return images;
    };

};

loadImages();

HTML:

<div id="loading">images loading...</div>
<div id="container" class="hide">
    <div></div><div></div><div></div><div></div><div></div>
</div>

CSS:

.hide {
    display: none;
}

#container div {
    background-size: 100px 100px;
    display: inline-block;
    height: 100px;
    width: 100px;    
}​

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