preload hidden CSS images

孤者浪人 提交于 2019-12-17 18:27:32

问题


I'm working on a jquery based homepage with 5 or so hidden divs, each containing several background css images.

The issue is that the browser doesn't load css images into the DOM until the visibility of the parent layer is shown, causing images to slowly load in when the layer becomes visible.

Solutions I've already considered:

  • CSS sprites (too much work to redesign for this, and wont really work when showing/hiding divs)
  • This jQuery plugin that auto-loads CSS background images (simply doesn't work for me as reported by many others).
  • preloading the images via js:

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

    This solution seems to load the image into the dom twice...once when the js loads it, and then again when the div layer that loads it becomes visible... so it makes 2 HTTP calls, thus not working.

Any other solutions for this problem that I'm missing?


回答1:


When you said other ways do you mean ones that don't use 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>

Other none JS ways are to place some html in your page somewhere so it's not seen:

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

or HTML...

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

...and CSS...

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

More JavaScript Methods:

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];
        }
    }
}

Then load the images using something like:

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



回答2:


CSS preloading is easy.

Example:

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



回答3:


Hard coding URLs like the other solutions suggest places a tax on code maintenance. It's relatively easy to avoid this and make a general solution with jQuery.

This function selects all hidden elements, checks if they have background images, and then loads them into a hidden dummy element.

$(':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;
  }
});



回答4:


"This solution seems to load the image into the dom twice...once when the js loads it, and then again when the div layer that loads it becomes visible...so it makes 2 http calls, thus not working"

The second http request should respond in a 304 (not modified), so I guess that's ok? Another options is to load the image via jQuery and then insert as background image inline via DOM, like:

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]');



回答5:


Browsers are beginning to support prefetch and preload properties of the <link> element's rel="..." property.

Addy Osmani's post about the preload and prefetch properties is excellent and describes when they should be used:

Preload is an early fetch instruction to the browser to request a resource needed for a page (key scripts, Web Fonts, hero images).

Prefetch serves a slightly different use case — a future navigation by the user (e.g between views or pages) where fetched resources and requests need to persist across navigations. If Page A initiates a prefetch request for critical resources needed for Page B, the critical resource and navigation requests can be completed in parallel. If we used preload for this use case, it would be immediately cancelled on Page A’s unload.

The element is used like so:

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

I'm designing a form with multiple steps, and each has a different background image. This pattern resolves a "blink" between steps as Chrome downloads the next background image.



来源:https://stackoverflow.com/questions/1787319/preload-hidden-css-images

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!