【问题标题】:How do I pre-cache images for quick viewing with javascript?如何预缓存图像以便使用 javascript 快速查看?
【发布时间】:2008-11-13 18:17:56
【问题描述】:

我有一个网页,我希望用户在将鼠标放在图像的某个部分上时看到新图像。我使用了图像映射。

<img src="pic.jpg" usemap="#picmap" />
<map id="picmap" name="picmap"><area shape="rect" coords ="10,20,30,40"
onMouseOver="mouse_on_write('mouse is on spot')"
onMouseOut="mouse_off('mouse is off spot')"
href="http://www....html" target="_blank" />
</map>
<p id="desc"></p>

我在标题中定义了这些函数:

 <script type="text/javascript">
 function mouse_off(txt)
    {
    document.getElementById("desc").innerHTML=txt;
    document.p1.src="pic.jpg";
    }
 function mouse_on_write(txt)
    {
    document.getElementById("desc").innerHTML=txt;
    document.p1.src="pic2.jpg";
  </script>

它可以工作,但速度很慢。当鼠标放在第二张图片上时,需要几秒钟才能出现;我的临时解决方案是大幅减小图像的大小,因为它们很大(在 2.5mb 时它们现在可以快速切换,但仍然不是无缝的)。 如何在不降低画质的情况下让图像切换更加无缝? 再想一想,我意识到我也可以同时显示两个图像,无论是小比例还是大比例,鼠标悬停时它们会切换位置;我该怎么做?这会减少延迟吗?

【问题讨论】:

  • 顺便说一句,您可能不希望对您的用户造成 2.5 MB 的图像。您要填充的空间尺寸是多少?

标签: javascript html


【解决方案1】:

从 Javascript 1.6 开始,这可以在没有任何命名变量的情况下完成:

imageList.forEach( function(path) { new Image().src=path } );

【讨论】:

    【解决方案2】:

    您不需要创建任何页面元素,都可以使用 JavaScript 预加载:

    tempImg = new Image()
    tempImg.src="pic2.jpg"
    

    编辑:

    如果图片很多,可以使用穷人的多预加载器:

    preloads = "red.gif,green.gif,blue.gif".split(",")
    var tempImg = []
    
    for(var x=0;x<preloads.length;x++) {
        tempImg[x] = new Image()
        tempImg[x].src = preloads[x]
    }
    

    【讨论】:

    • 这个方法对我不起作用。我需要预加载,因为我在重新加载页面之前向用户显示了一条消息——我知道这是一个极端情况。但是,如果我将它放在 DOM 中,这将有效:&lt;img src="/images/icons/icon.png" style="visibility:hidden; height:0px; width:0px;" /&gt;。将高度和宽度强制为零可以防止它损坏视图,无论它在哪里,而visibility:hidden 使浏览器加载图像。
    • 快速提示:不惜一切代价避免使用经典的for 循环。请改用forEach 数组辅助函数。
    【解决方案3】:

    您要做的是在幕后预加载图像。

    然后,当鼠标悬停时,浏览器的缓存中已经有该图像,并且会非常快速地切换它。

    function preloadImage(imagePath)
    {
        var img = document.createElement('IMG');
        img.src = imagePath;        
    }
    
    preloadImage('BigImage');
    

    【讨论】:

      【解决方案4】:

      使用 sprite 执行此操作是一个很好的解决方案,因为您不必等待加载新图像。精灵通过将两个图像合二为一并在鼠标悬停时更改背景偏移来工作。

      您甚至可以改用 CSS,以获得更快的结果。这个here有一个很好的教程。

      【讨论】:

      • 精灵没有得到足够的爱。玩的不错。
      • 仅 2 张图像似乎有点矫枉过正。 Diodeus 的解决方案似乎更简单。但这取决于我猜是否可以使用javascript。
      • 如果你有+500个imgs就没有用了,js更适合预缓存下X张照片
      • @davefrassoni 我不知道你从哪里得到这个标准,但它不是 OP。除此之外,不要在这些问题上遵循 11 岁的建议。使用服务人员或其他东西。
      【解决方案5】:

      您还可以将两个图像放在同一个文件中并上下偏移。如果它应该影响你用鼠标越过的元素,它可能看起来像

      a {  
        background-image: url(back.png);  
        background-repeat: no-repeat;  
        background-attachment:fixed;  
        background-position: 0 0;
      }
      
      a:hover {
        background-image: url(back.png);  
        background-repeat: no-repeat;  
        background-attachment:fixed;  
        background-position: 0 20px;  
      }  
      

      这样它可以在没有 javascript 的情况下工作。

      如果我正确理解您的情况,您仍然需要 javascript,但您仍然可以通过这种方式“预加载”图像。

      【讨论】:

        【解决方案6】:

        Diodeus 的巧妙解决方案。但是,除非有充分的理由不这样做,否则您应该真正考虑使用精灵。设置它们需要一些工作,但净效率确实值得。

        这种方法是 Steve Souder 的High Performance Web Sites 中的第一条规则。

        “规则 1 - 减少 HTTP 请求”

        祝你好运,玩得开心。 - D.

        【讨论】:

        • 虽然我同意,但由于提问者的性质,看起来像精灵之类的东西可能有点太具有挑战性了。
        【解决方案7】:

        我注意到到目前为止,“预加载”到 .src 并不能在所有浏览器中始终如一地工作 - IE7 仍然无法弄清楚如何缓存/使用预加载的图像 - 你可以清楚地看到每次鼠标悬停时都会发出一个服务器请求。

        我所做的是通过标准 HTML 放置加载所有图像,然后打开和关闭 style.display。

        【讨论】:

          【解决方案8】:

          使用display: none;,然后在您想要显示它时让Javascript 将其更改为display: inline。这样做的另一个好处是能够将图像准确地放在页面源中您想要的位置,而不必稍后使用 Javascript 添加它。

          【讨论】:

            【解决方案9】:

            这是我的做法,在纯 JavaScript 中:

            var myImgs = ['path/to/img1.jpg', 'path/to/img2.gif'];
            
            function preload(imgs) {
                var img;
                for (var i = 0, len = imgs.length; i < len; ++i) {
                    img = new Image();
                    img.src = imgs[i];
                }
            }
            
            preload(myImgs);
            

            也就是说,ALassek 关于使用 CSS sprites 的建议是一个很好的建议,如果你有能力去做的话。 sprite 的优点有很多:更少的 HTTP 请求,更小的下载大小(通常),在没有启用 JavaScript 的情况下也能工作。

            【讨论】:

              【解决方案10】:

              http://www.filamentgroup.com/lab/update_automatically_preload_images_from_css_with_jquery/

              当我们第一次启动实验室时,我们发布了一个 jQuery 插件,它可以自动预加载 CSS 文件中引用的所有图像。我们发现该脚本在开发快速应用程序方面非常有帮助,在这些应用程序中,图像总是在我们需要时准备好。这篇文章描述了对脚本的重大更新,这将使其更容易集成到现有项目中。

              【讨论】:

              • 死链接。我找不到替代品(主要是因为我很懒)
              猜你喜欢
              • 2023-04-03
              • 2013-05-17
              • 2019-06-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多