wait until images in background (css) are loaded

时间:2022-08-23 18:09:02

Let's say we have a slideshow of pictures. the thumbnails of those pictures are showed in div wrapper with a slider (that I created with Jquery) and each image is included in a <li> with a CSS background set, which of course represents the image. I chose to use a background-image for a layout matter because they all are different in size and aspect ratio.

假设我们有一个图片幻灯片。这些图片的缩略图显示在带有滑块的div包装器中(我用Jquery创建),每个图像都包含在带有CSS背景集的

  • 中,当然这代表图像。我选择使用背景图像来处理布局问题,因为它们的大小和宽高比都不同。

  • The images comes from a db and are dynamically created.

    图像来自数据库并动态创建。

    What I wanna do is:

    我想做的是:

    show a "loading" message over every <li> and wait until the background(image) is loaded in the cache and then show it with a fadeIn. They only way I can think of (not that I can since I'm not very sure how and if its doable) is:

    在每个

  • 上显示“加载”消息,并等待后台(图像)加载到缓存中,然后使用fadeIn显示它。他们只有我能想到的方式(不是我可以,因为我不太确定如何以及它是否可行)是:

    • temporally unset the background for every <li> while showing the "loading" message
    • 在显示“加载”消息时,暂时取消每个

    • 的背景

    • make a loop for every background to get the image url
    • 为每个背景制作一个循环以获取图像网址

    • use the $.get function to load it and then do whatever I want after loading
    • 使用$ .get函数加载它,然后在加载后执行我想要的任何操作

    Beside the doable thing, this would imply they would load in sequence so if one won't load for some reason the script will never continue!

    除了可行的事情,这意味着他们将按顺序加载,所以如果由于某种原因不会加载脚本永远不会继续!

    I've seen some sites that use JS to load images only when its visible by the browser, maybe this could be the same case I'm looking for, since I'm using a scroller and only a part of the images are showed at once and when the page loads

    我已经看到一些使用JS加载图像的网站只有在浏览器可见时才加载,也许这可能与我正在寻找的情况相同,因为我使用的是滚动条,只有部分图像显示在一旦页面加载

    5 个解决方案

    #1


    8  

    Well, I think things may be simpler if you just use img tags, but if you do want to use background images then I could only come up with a work around.

    好吧,我认为如果你只是使用img标签,事情可能会更简单,但如果你确实想要使用背景图像,那么我只能想出一个解决方案。

    The trick is to create a new image (using the Javascript image object), and make sure it's loaded, but this image isn't displayed. Once the image is loaded and in the cache, that image will be available as a background image in your gallery.

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

    So, all you have to do is make sure that you only change the background image of the LI of an image after the corresponding image is loaded. You can load all LIs with a default "loading" image initially.

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

    So your code would be something like:

    所以你的代码将是这样的:

    HTML (the style definitions for the loading image could be in your external style sheet):

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

    <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>
    

    Your jQuery / Javascript:

    你的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;​
    

    You would have to have the appropriate CSS / ids etc for each LI, and you would have to adapt the above to the loop or function you use to show your gallery.

    您必须为每个LI提供适当的CSS / ID等,并且您必须使上述内容适应您用于显示图库的循环或函数。

    Here's a jsFiddle example. (for testing purposes it's a big image, so it takes a while to load).

    这是一个jsFiddle示例。 (出于测试目的,它是一个很大的图像,所以加载需要一段时间)。

    #2


    2  

    You can you a css trick instead of some long javascript code.
    Here you can do it like this:

    你可以使用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');
    }
    


    Explanation:
    The Images of the slideshow will be the background of div contained in the li. Until the images are loaded the background will be transparent, which will show the background of the li which is the animated loading gif.
    In simple terms loading image of li will be shown until slideshow image contained in the div is loaded.

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

    #3


    0  

    well, i think that maybe you are making things too complicated. I'm not really sure why you're using css background when the images could be inside a tag. You say the reason is because your images are dynamically created... and i dont understand that.

    好吧,我想也许你的事情太复杂了。当图像可能位于标签内时,我不确定为什么要使用css背景。你说原因是因为你的图像是动态创建的...我不明白。

    What you could do is create a page that returns the images, maybe you could use some parameter... something like the image size:

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

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

    then all you need to do is put this url inside the SRC of the img tag... If you want to, you could pre-load the image when the page is loaded..or when your slider is moving

    那么你需要做的就是将这个url放在img标签的SRC中...如果你愿意,你可以在页面加载时预加载图像。或者当你的滑块移动时

    Or maybe i didn't understood your problem =D

    或者也许我没有理解你的问题= D.

    #4


    0  

    The solution I use from this is have two layers of elements.

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

    One layer is a case that has the background loading symbol as the background. This is always seen. Then in a second layer above, I place the element with the images and use a jQuery .ready() function with a .delay() and .fade().

    一层是具有背景加载符号作为背景的案例。总是可以看到这一点。然后在上面的第二层中,我将元素放在图像中,并使用带有.delay()和.fade()的jQuery .ready()函数。

    Because this is convoluted to explain, I'll show what I do:

    因为这是令人费解的解释,我将展示我的所作所为:

        <!-- 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(){});
        });
      });
    

    The delay and fade makes the loading time seem intentional, while the .ready() will wait until the element is completely loaded.

    延迟和淡入使得加载时间看起来是有意的,而.ready()将等到元素完全加载。

    By having a separate background layer, you don't have to worry about manipulating anything in addition to the slider. To add an additional effect, you can make a callback to the image load that does a fade to the loading animation.

    通过具有单独的背景图层,除了滑块之外,您不必担心操纵任何内容。要添加其他效果,您可以对图像加载进行回调,该图像加载会对加载动画进行淡入淡出。

    #5


    0  

    It looks for elements with src attribute or backgroundImage css property and calls an action function when theirs images loaded.

    它查找具有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);
        });
    }
    

    #1


    8  

    Well, I think things may be simpler if you just use img tags, but if you do want to use background images then I could only come up with a work around.

    好吧,我认为如果你只是使用img标签,事情可能会更简单,但如果你确实想要使用背景图像,那么我只能想出一个解决方案。

    The trick is to create a new image (using the Javascript image object), and make sure it's loaded, but this image isn't displayed. Once the image is loaded and in the cache, that image will be available as a background image in your gallery.

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

    So, all you have to do is make sure that you only change the background image of the LI of an image after the corresponding image is loaded. You can load all LIs with a default "loading" image initially.

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

    So your code would be something like:

    所以你的代码将是这样的:

    HTML (the style definitions for the loading image could be in your external style sheet):

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

    <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>
    

    Your jQuery / Javascript:

    你的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;​
    

    You would have to have the appropriate CSS / ids etc for each LI, and you would have to adapt the above to the loop or function you use to show your gallery.

    您必须为每个LI提供适当的CSS / ID等,并且您必须使上述内容适应您用于显示图库的循环或函数。

    Here's a jsFiddle example. (for testing purposes it's a big image, so it takes a while to load).

    这是一个jsFiddle示例。 (出于测试目的,它是一个很大的图像,所以加载需要一段时间)。

    #2


    2  

    You can you a css trick instead of some long javascript code.
    Here you can do it like this:

    你可以使用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');
    }
    


    Explanation:
    The Images of the slideshow will be the background of div contained in the li. Until the images are loaded the background will be transparent, which will show the background of the li which is the animated loading gif.
    In simple terms loading image of li will be shown until slideshow image contained in the div is loaded.

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

    #3


    0  

    well, i think that maybe you are making things too complicated. I'm not really sure why you're using css background when the images could be inside a tag. You say the reason is because your images are dynamically created... and i dont understand that.

    好吧,我想也许你的事情太复杂了。当图像可能位于标签内时,我不确定为什么要使用css背景。你说原因是因为你的图像是动态创建的...我不明白。

    What you could do is create a page that returns the images, maybe you could use some parameter... something like the image size:

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

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

    then all you need to do is put this url inside the SRC of the img tag... If you want to, you could pre-load the image when the page is loaded..or when your slider is moving

    那么你需要做的就是将这个url放在img标签的SRC中...如果你愿意,你可以在页面加载时预加载图像。或者当你的滑块移动时

    Or maybe i didn't understood your problem =D

    或者也许我没有理解你的问题= D.

    #4


    0  

    The solution I use from this is have two layers of elements.

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

    One layer is a case that has the background loading symbol as the background. This is always seen. Then in a second layer above, I place the element with the images and use a jQuery .ready() function with a .delay() and .fade().

    一层是具有背景加载符号作为背景的案例。总是可以看到这一点。然后在上面的第二层中,我将元素放在图像中,并使用带有.delay()和.fade()的jQuery .ready()函数。

    Because this is convoluted to explain, I'll show what I do:

    因为这是令人费解的解释,我将展示我的所作所为:

        <!-- 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(){});
        });
      });
    

    The delay and fade makes the loading time seem intentional, while the .ready() will wait until the element is completely loaded.

    延迟和淡入使得加载时间看起来是有意的,而.ready()将等到元素完全加载。

    By having a separate background layer, you don't have to worry about manipulating anything in addition to the slider. To add an additional effect, you can make a callback to the image load that does a fade to the loading animation.

    通过具有单独的背景图层,除了滑块之外,您不必担心操纵任何内容。要添加其他效果,您可以对图像加载进行回调,该图像加载会对加载动画进行淡入淡出。

    #5


    0  

    It looks for elements with src attribute or backgroundImage css property and calls an action function when theirs images loaded.

    它查找具有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);
        });
    }