【问题标题】:preload hidden CSS images预加载隐藏的 CSS 图像
【发布时间】:2010-12-19 17:28:55
【问题描述】:

我正在开发一个基于 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 调用,因此无法正常工作。

我还没有解决此问题的任何其他解决方案吗?

【问题讨论】:

    标签: jquery css image preload


    【解决方案1】:

    当您说其他方式时,您是指不使用 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>
    

    【讨论】:

    • 感谢所有建议!明天我会试一试,看看有什么效果。我确实尝试了 1x1 div 方法,但我正在使用的 rails 应用程序将缓存哈希分配给图像 url 的末尾......因此浏览器将它们视为与 css 中的图像不同的图像。
    【解决方案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]');
    

    【讨论】:

      【解决方案3】:

      像其他解决方案一样,硬编码 URL 建议对代码维护征税。避免这种情况并使用 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;
        }
      });
      

      【讨论】:

      • 请将第二个替换更改为:var imgUrl = backgroundImage.replace(/"/g,"").replace(/url\(|\)|"|'$/ig, ""); 这是有效的 css background-image: url('.... 例如注意单引号
      【解决方案4】:

      CSS 预加载很容易。

      示例

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

      【讨论】:

        【解决方案5】:

        浏览器开始支持&lt;link&gt; 元素的rel="..." 属性的prefetchpreload 属性。

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

        预加载是向浏览器发送请求的早期获取指令 页面所需的资源(关键脚本、Web 字体、主图)。

        预取服务的用例略有不同 — 未来导航 获取资源的用户(例如视图或页面之间)和 请求需要在导航中持续存在。如果页面 A 发起一个 对页面 B 所需的关键资源的预取请求, 关键资源和导航请求可以在 平行线。如果我们在这个用例中使用预加载,它将是 在页面 A 卸载时立即取消。

        元素的使用方式如下:

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

        我正在设计一个包含多个步骤的表单,每个步骤都有不同的背景图像。当 Chrome 下载下一个背景图片时,此模式可解决步骤之间的“闪烁”问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-25
          • 1970-01-01
          • 2011-04-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-03
          • 2019-07-03
          相关资源
          最近更新 更多