预加载隐藏的CSS图像

时间:2009-11-24 01:58:17

标签: jquery css image preload

我正在开发一个基于jquery的主页,其中包含5个左右隐藏的div,每个div包含几个背景css图像。

问题在于,在显示父图层的可见性之前,浏览器不会将css图像加载到DOM中,从而导致图像在图层变得可见时缓慢加载。

我已经考虑过的解决方案:

  • CSS sprites(为此重新设计的工作太多,在显示/隐藏div时不会真正起作用)
  • This jQuery plugin自动加载CSS背景图片(根据许多其他人的报告,对我来说根本不起作用)。
  • 通过js预加载图片:

    $(function() {
    function preloadImg(image) {
      var img = new Image();
      img.src = image;
    }
    
    preloadImg('/images/home/search_bg_selected.png');
    });
    

    这个解决方案似乎将图像加载到dom中两次......一旦js加载它,然后当加载它的div层变得可见时再次......所以它会进行2次HTTP调用,因此无效。

我缺少这个问题的其他解决方案吗?

5 个答案:

答案 0 :(得分:13)

当你说其他方式时,你的意思是那些不使用Javascript的方式吗?

<script language="JavaScript">
function preloader() 
{
     // counter
     var i = 0;

     // create object
     imageObj = new Image();

     // set image list
     images = new Array();
     images[0]="image1.jpg"
     images[1]="image2.jpg"
     images[2]="image3.jpg"
     images[3]="image4.jpg"

     // start preloading
     for(i=0; i<=3; i++) 
     {
          imageObj.src=images[i];
     }
} 
</script>

其他没有JS的方法是在你的页面中放置一些html,所以它没有被看到:

<image src="picture.jpg" width="1" height="1" border="0">

或HTML ...

<img src="images/arrow-down.png" class="hiddenPic" />

...和CSS ...

.hiddenPic {
    height:1px;
    width:1px;
}

更多JavaScript方法:

function preload(images) {
    if (document.images) {
        var i = 0;
        var imageArray = new Array();
        imageArray = images.split(',');
        var imageObj = new Image();
        for(i=0; i<=imageArray.length-1; i++) {
            //document.write('<img src="' + imageArray[i] + '" />');// Write to page (uncomment to check images)
            imageObj.src=images[i];
        }
    }
}

然后使用以下内容加载图像:

<script type="text/javascript">
preload('image1.jpg,image2.jpg,image3.jpg');
</script>

答案 1 :(得分:7)

像其他解决方案一样的硬编码网址会对代码维护征税。避免这种情况并使用jQuery制作通用解决方案相对容易。

此函数选择所有隐藏元素,检查它们是否有背景图像,然后将它们加载到隐藏的虚拟元素中。

$(':hidden').each(function() {
  //checks for background-image tab
  var backgroundImage = $(this).css("background-image");
  if (backgroundImage != 'none') {
    var imgUrl = backgroundImage.replace(/"/g,"").replace(/url\(|\)$/ig, "");
    $('<img/>')[0].src = imgUrl;
  }
});

答案 2 :(得分:7)

CSS预加载很简单。

示例

body:after{
    display:none;
    content: url(img01.png) url(img02.png) url(img03.png) url(img04.png)
}

答案 3 :(得分:2)

  

“此解决方案似乎加载了图像   进入dom两次......一次当js   加载它,然后再加载div   加载它的图层变成了   可见...所以它进行2次http调用,   因此没有工作“

第二个http请求应该在304(未修改)中响应,所以我猜这没关系? 另一个选择是通过jQuery加载图像,然后通过DOM插入内嵌作为背景图像,如:

jQuery.fn.insertPreload = function(src) {
    return this.each(function() {
        var $this = $(this);
        $(new Image()).load(function(e) {
            $this.css('backgroundImage','url('+src+')');
        }).attr('src',src);
    });
};

$('div').insertPreload('[huge image source]');

答案 4 :(得分:1)

浏览器开始支持prefetch元素的preload属性的<link>rel="..."属性。

Addy Osmani的post about the preload and prefetch properties非常出色,并描述了何时应该使用它们:

  

Preload是浏览器请求a的早期提取指令   页面所需的资源(关键脚本,Web字体,英雄图像)。

     

预取提供了一个稍微不同的用例 - 未来的导航   获取资源的用户(例如视图或页面之间)   请求需要在导航中持续存在。如果Page A启动了   对页面B所需的关键资源的预取请求   关键资源和导航请求可以在中完成   平行。如果我们使用预载这个用例,那就是   在页面A卸载时立即取消。

元素的使用方式如下:

<link rel="preload" as="image" href="https://your.url.com/yourimage.jpg" />

我正在设计一个包含多个步骤的表单,每个表单都有不同的背景图像。这种模式解决了#34;眨眼&#34;在Chrome下载下一张背景图片的步骤之间。