how to preload large size image?

2020-03-04 09:20发布

问题:

i have certain links, on mouse over of those links I am changing <div> background image

jQuery I have used is-

function imgchange()
    {
        $('.smenu li').mouseover( function(){
        var src = $(this).find('a').attr('href');
        $('.hbg').css('background-image', 'url(' + src + ')');
        $(this).find('hbg').attr('title', 'my tootip info');
        });     
    }

It is working fine but the problem is when I running it on server images takes 3-4 sec to be changed on change, but the second time I do mouse over images are getting changed instantly, I think this is because of browser stored images in cache. So I added one javascript to preload images on page onLoad() ivent -

<script language = "JavaScript">
function preloader() 
{
heavyImage = new Image(); 
heavyImage.src = "images/soluinfo1.jpg";
heavyImage.src = "images/soluinfo2.jpg";
heavyImage.src = "images/soluinfo3.jpg";
heavyImage.src = "images/soluinfo4.jpg";
heavyImage.src = "images/soluinfo5.jpg";
heavyImage.src = "images/soluinfo6.jpg";
heavyImage.src = "images/soluinfo7.jpg";
}
</script>

<body onLoad="javascript:preloader()">

but this script has not solved my problem.what should I do?

回答1:

@Richard's answer (sprites) is probably the best one for what you are after, but the reason your code is not working is that in most browsers, only the last heavyImage.src="" is given enough time to actually register with the browser as an actual request. You're creating only one Image object setting and resetting the .src attribute faster than the browser can request the files (I think modern JavaScript engines take the added step of removing all the intermediate .src statements specifically because of this).

There are a couple of ways to fix this. The easiest is to create multiple Image objects, one for each image. And the easiest way to do that is through something like this:

<script type="text/javascript">
function preloader() 
{
    function doPreload(strImagePath) 
    {
        var heavyImage = new Image();
        heavyImage.src = strImagePath;
    }

    var arrImages = ["images/soluinfo1.jpg","images/soluinfo2.jpg","images/soluinfo3.jpg","images/soluinfo4.jpg","images/soluinfo5.jpg","images/soluinfo6.jpg","images/soluinfo7.jpg"];
    for (var i = 0; i < arrImages.length; i++) {
        doPreload(arrImages[i]);
    }
}
</script>

By putting the heavyImage variable inside its own function (remember to use the var keyword), you're ensuring that the Image object exists inside its own dedicated scope.

Another way to do this is to attach a "load" event listener to a single heavyImage. Every time the image finishes loading, go fetch the next image. The disadvantage to this method is that your images will be loaded one at a time (bad for navigation images, but great for, say, and image gallery), whereas the first technique will fetch the images in parallel (typicallly four at a time).



回答2:

You might find it easier to change your approach and use CSS sprites (and another article). Then you would just have one image referenced, and you use CSS to set which part of that image gets shown in which scenario.

This assumes that the images you're using are under your control and you can use an image editor to combine them into one large image.