草庐IT

javascript - 预加载图像的最佳方式

coder 2024-07-20 原文

预加载图像的最佳方式是什么?我正在尝试创建一个包含大约 59 张 png 图像的图像选项卡。这是我到目前为止的代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
  <head>
    <title>Checklist</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="stylesheet" type="text/css" href="/systems_hr/Style%20Library/globalstyles_test.css">
    <style type="text/css">
      #innerframe {
                width: 100%;
                height: 63em;
        }
    </style>
    <script type="text/javascript" src="/systems_hr/Style%20Library/JavaScripts/styles.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>    
    <script type="text/javascript">    

      var id1 = new Image();
      id1.src = "images/id1.png";

      var id11 = new Image();
      id11.src = "images/id1-1.png";

      var id12 = new Image();
      id12.src = "images/id1-2.png";

      var id13 = new Image();
      id13.src = "images/id1-3.png";  

      var id2 = new Image();
      id2.src = "images/id2.png";

      var id21 = new Image();
      id21.src = "images/id2-1.png";

      var id22 = new Image();
      id22.src = "images/id2-2.png";

      var id23 = new Image();
      id23.src = "images/id2-3.png";    

      var id3 = new Image();
      id3.src = "images/id3.png";

      var id31 = new Image();
      id31.src = "images/id3-1.png";

      var id32 = new Image();
      id32.src = "images/id3-2.png";

      var id33 = new Image();
      id33.src = "images/id3-3.png";       

      var id4 = new Image();
      id4.src = "images/id4.png";

      var id41 = new Image();
      id41.src = "images/id4-1.png";

      var id42 = new Image();
      id42.src = "images/id4-2.png";

      var id43 = new Image();
      id43.src = "images/id4-3.png"; 

      var iw1 = new Image();
      iw1.src = "images/iw1.png"

      var iw11 = new Image();
      iw11.src = "images/iw1-1.png"

      var iw12 = new Image();
      iw12.src = "images/iw1-2.png"

      var iw13 = new Image();
      iw13.src = "images/iw1-3.png"

      var iw14 = new Image();
      iw14.src = "images/iw1-4.png"

      var iw2 = new Image();
      iw2.src = "images/iw2.png"

      var iw21 = new Image();
      iw21.src = "images/iw2-1.png"

      var iw22 = new Image();
      iw22.src = "images/iw2-2.png"

      var iw23 = new Image();
      iw23.src = "images/iw2-3.png"

      var iw24 = new Image();
      iw24.src = "images/iw2-4.png"  

            var iw3 = new Image();
      iw3.src = "images/iw3.png"

      var iw31 = new Image();
      iw31.src = "images/iw3-1.png"

      var iw32 = new Image();
      iw32.src = "images/iw3-2.png"

      var iw33 = new Image();
      iw33.src = "images/iw3-3.png"

      var iw34 = new Image();
      iw34.src = "images/iw3-4.png"  

      var iw4 = new Image();
      iw4.src = "images/iw4.png"

      var iw41 = new Image();
      iw41.src = "images/iw4-1.png"

      var iw42 = new Image();
      iw42.src = "images/iw4-2.png"

      var iw43 = new Image();
      iw43.src = "images/iw4-3.png"

      var iw44 = new Image();
      iw44.src = "images/iw4-4.png"      

      var im1 = new Image();
      im1.src = "images/im1.png"

      var im11 = new Image();
      im11.src = "images/im1-1.png"

      var im12 = new Image();
      im12.src = "images/im1-2.png"

      var im13 = new Image();
      im13.src = "images/im1-3.png"

      var im2 = new Image();
      im2.src = "images/im2.png"

      var im21 = new Image();
      im21.src = "images/im2-1.png"

      var im22 = new Image();
      im22.src = "images/im2-2.png"

      var im23 = new Image();
      im23.src = "images/im2-3.png"

      var im3 = new Image();
      im3.src = "images/im3.png"

      var im31 = new Image();
      im31.src = "images/im3-1.png"

      var im32 = new Image();
      im32.src = "images/im3-2.png"

      var im33 = new Image();
      im33.src = "images/im3-3.png"

      function changeFrame (frameSRC)
      {
        var myFrame = document.getElementById('fraContent'); 
        myFrame.contentWindow.location =  frameSRC;
      }

      function rolloverArea(area, orgImgSrc, tgtImgSrc, orgCursor, tgtCursor) // jQuery script for rollover effect
      {
        $("#imgTab").attr("src", orgImgSrc);
        $(area).hover(
          function()
            {
              $("#imgTab").attr("src", tgtImgSrc);
              $("#imgTab").css("cursor",tgtCursor);
            },
          function()
            {
              $("#imgTab").attr("src", orgImgSrc);
              $("#imgTab").css("cursor",orgCursor);
             }
        );
      }

      /*function initLoad ()
      {
      }*/

      function changeImgState(img) // tab interface of Day Week and Month arrows
      {
        var myImgTab = document.getElementById("imgTab");

        switch (img)
        {
          case 'id1':

            myImgTab.src = id1.src;

            // Rollover effect for the image
            rolloverArea("#area1",id1.src,id1.src,"auto","auto");
            rolloverArea("#area2",id1.src,id11.src,"auto","pointer");
            rolloverArea("#area3",id1.src,id12.src,"auto","pointer");
            rolloverArea("#area4",id1.src,id13.src,"auto","pointer");
            rolloverArea("#area5",id1.src,id1.src,"auto","auto");

            // onClick effect
            $("#area2").click(function() {
              $("#innerframe").attr("src","D2.html");
              changeImgState("id2");
              }
             );

             $("#area3").click(function() {
              $("#innerframe").attr("src","D3.html");
              changeImgState("id3");
              }
             );

             $("#area4").click(function() {
              $("#innerframe").attr("src","D4.html");
              changeImgState("id4");
              }
             );

            break;
          case 'id2':

            myImgTab.src = id2.src;

            // Rollover effect for the image
            rolloverArea("#area1",id2.src,id21.src,"auto","pointer");
            rolloverArea("#area2",id2.src,id2.src,"auto","auto");
            rolloverArea("#area3",id2.src,id22.src,"auto","pointer");
            rolloverArea("#area4",id2.src,id23.src,"auto","pointer");
            rolloverArea("#area5",id2.src,id2.src,"auto","auto");

            // onClick effect
            $("#area1").click(function() {
              $("#innerframe").attr("src","D1.html");
              changeImgState("id1");
              }
             );

             $("#area3").click(function() {
              $("#innerframe").attr("src","D3.html");
              changeImgState("id3");
              }
             );

             $("#area4").click(function() {
              $("#innerframe").attr("src","D4.html");
              changeImgState("id4");
              }
             );

            break;

          case 'id3':

            myImgTab.src = id3.src;

            // Rollover effect for the image
            rolloverArea("#area1",id3.src,id31.src,"auto","pointer");
            rolloverArea("#area2",id3.src,id32.src,"auto","pointer");
            rolloverArea("#area3",id3.src,id3.src,"auto","auto");
            rolloverArea("#area4",id3.src,id33.src,"auto","pointer");
            rolloverArea("#area5",id3.src,id3.src,"auto","auto");

            // onClick effect
            $("#area1").click(function() {
              $("#innerframe").attr("src","D1.html");
              changeImgState("id3");
              }
             );

            $("#area2").click(function() {
              $("#innerframe").attr("src","D2.html");
              changeImgState("id2");
              }
             );

             $("#area4").click(function() {
              $("#innerframe").attr("src","D4.html");
              changeImgState("id4");
              }
             );

            break;

          case 'id4':

            myImgTab.src = id4.src;

            // Rollover effect for the image
            rolloverArea("#area1",id4.src,id41.src,"auto","pointer");
            rolloverArea("#area2",id4.src,id42.src,"auto","pointer");
            rolloverArea("#area3",id4.src,id43.src,"auto","pointer");
            rolloverArea("#area4",id4.src,id4.src,"auto","auto");
            rolloverArea("#area5",id4.src,id4.src,"auto","auto");

            // onClick effect
            $("#area1").click(function() {
              $("#innerframe").attr("src","D1.html");
              changeImgState("id3");
              }
             );

            $("#area2").click(function() {
              $("#innerframe").attr("src","D2.html");
              changeImgState("id2");
              }
             );

             $("#area4").click(function() {
              $("#innerframe").attr("src","D4.html");
              changeImgState("id4");
              }
             );

            break;

          case 'iw1':

            myImgTab.src = iw1.src;

            rolloverArea("#area1",iw1.src,iw1.src,"auto","auto");
            rolloverArea("#area2",iw1.src,iw11.src,"auto","pointer");
            rolloverArea("#area3",iw1.src,iw12.src,"auto","pointer");
            rolloverArea("#area4",iw1.src,iw13.src,"auto","pointer");
            rolloverArea("#area5",iw1.src,iw14.src,"auto","pointer");

            break;
          case 'im1': 

            myImgTab.src = im1.src;

            rolloverArea("#area1",im1.src,im1.src,"auto","auto");
            rolloverArea("#area2",im1.src,im11.src,"auto","pointer");
            rolloverArea("#area3",im1.src,im12.src,"auto","pointer");
            rolloverArea("#area4",im1.src,im13.src,"auto","pointer");
            rolloverArea("#area5",im1.src,im1.src,"auto","auto");           
            break;
        }

      } 

      function changeTab(tab)
      {   
        switch(tab)     
        {
          case 'day1':
            var myTab = document.getElementById("day1");

            document.getElementById("week1").className = "active";
            document.getElementById("month1").className = "active";        
            myTab.className = "current"; 

            changeImgState("id1");
            $("#innerframe").attr("src","D1.html");

            break; 
          case 'week1':
            document.getElementById("day1").className = "active";
            document.getElementById("month1").className = "active";         
            document.getElementById("week1").className = "current";

            changeImgState("iw1");
            $("#innerframe").attr("src","W1.html");

            break;
          case 'month1':
            document.getElementById("week1").className = "active";
            document.getElementById("day1").className = "active";         
            document.getElementById("month1").className = "current";

            changeImgState("im1");
            $("#innerframe").attr("src","M1.html");

            break;
        }  

      }

      function test(tab)
      {
        alert(document.getElementById.id + " " + document.getElementById(tab).className)
      }
    </script>

  </head>
  <body onload="changeTab('day1');">
  <table border="0" width="100%">
  <tr>
    <td colspan="2" align="left">
      <div id="navcontainer">
        <ul id="navlist">
          <li><a class="active" id="day1" onclick="changeTab('day1');">FIRST DAY</a></li>
          <li><a class="active" id="week1" onclick="changeTab('week1');">FIRST WEEK</a></li>
          <li><a class="active" id="month1" onclick="changeTab('month1');">FIRST 30-DAYS</a></li>
        </ul>
      </div>
      <div id="page_viewer">
          <table border="0" width="1020px" cellpadding="0" cellspacing="0">
          <tr>
            <td>
              <img src="" style="border: 0px; width: 1000px; height: 72px;" alt="" usemap="#imgTabMap" name="imgTab" id="imgTab">
                <map id="imgTabMap" name="imgTabMap">
                  <area shape="rect" alt="" title="" coords="7,11,166,60" id="area1">
                  <area shape="rect" alt="" title="" coords="206,10,365,59" id="area2">
                  <area shape="rect" alt="" title="" coords="405,11,566,59" id="area3">
                  <area shape="rect" alt="" title="" coords="605,10,763,60" id="area4">
                  <area shape="rect" alt="" title="" coords="805,9,963,60" id="area5">
                  <!-- Created by Online Image Map Editor (http://www.maschek.hu/imagemap/index) -->
                </map>

            </td>
          </tr>
          <tr>
            <td width="100%">
              <iframe name="fraContent" id="innerframe" frameborder="0" scrolling="no" width="1000px"></iframe>
            </td>
          </tr>
          </table>
      </div>
      </td>
    </tr>
  </table>
  </body>
</html>

问题是现在我的页面需要一段时间才能加载,而且我不明白为什么单击选项卡似乎加载 iframe 很慢。加载 iframe 的 src 是否会导致再次预加载图像?在页面打开时加载相关图像而不是在点击时加载它们会更好吗?

我还找到了一个很好的替代方案,即 lieldulev 的并行加载脚本 (imagesQueue)但我不知道如何使用它。

顺便说一句,我不太精通 JavaScript,所以我正在努力边工作边学习。现在,我正在做的是实现我研究的技术并试图理解它们的功能,因此我的编码不像我希望的那样干净,有时甚至只是使用低效的“蛮力”代码以获得所需的效果。不过,我想对此进行改进,我们将不胜感激。

关于并行缓存脚本,这是我根据 Nick 的演示设置的测试页面:

        <html> 
        <head> 
            <title>liel's smij dev page</title> 
            <style type="text/css"> 
                #m1{
                    width:400px;
                    height:300px;
                    background-color:#adf;
                }
                canvas{
                    width:100%;
                    height:100%;
                }
                #show_me{float:left;width:100px;}
                #console_log{font-size:10px;float:right;}
            </style> 
            <script type="text/javascript" src="/systems_hr/Style%20Library/JavaScripts/imagesQueue.js"></script> 
        </head> 
        <body> 
                <h1>imagesQ(ueue.js) Demo</h1> 
                <!-- <img id="show_me" src="images/id1.png"> -->
                <img id="show_me" alt="">
                <div id="console_log">Log:</div> 
                <script type="text/javascript"> 
                    /*
                        imagesQueue Usage Example:
                    */
                    // the img element to show
                    show_img = document.getElementById('show_me');
                    log_e = document.getElementById('console_log');
                    log = function(output){log_e.innerHTML +='<br/>'+(output)};
                    imagesQueue = imagesQ;
                    // On every image loaded show progress:
                    imagesQueue.onLoaded = function()
                    {
                        show_img.src = imagesQueue.current.src;
                        var output = 'Q1 '+(imagesQueue.images.length)+"/"+(imagesQueue.qLength)+" ("+imagesQueue.current.src+") Loaded (onLoaded)";
                        log(output);
                    }
                    // When done say so.
                    imagesQueue.onComplete = function()
                    {
                        QueuesCompleteAll();
                    }
                    log('Q1 Queued 10 images (queue_images)');
                    var now =(new Date).getTime(); // make sure to get non-cached images
                    imagesQueue.queue_images(['images/id1.png'+now,
                                              'images/id1-1.png'+now,
                                               'images/id1-2.png'+now,
                                               'images/id1-3.png'+now,
                                                'images/id2.png'+now,
                                                'images/id2-1.png'+now,
                                                'images/id2-2.png'+now,
                                                'images/id2-3.png'+now,
                                                'images/id3.png'+now,
                                                'images/id3-1.png'+now]); 

                    log('Starting the queue (process_queue)');
                    var start = (new Date).getTime();
                    imagesQueue.process_queue();
                    log('This is the next line in the code after process_queue, to avoid this, you should design create a function for the rest of your code and call it upon onComplete.');
                    function QueuesCompleteAll(){
                        var diff = (new Date).getTime() - start;
                        log('All Done ('+diff+'ms)');
                    }
                </script> 
        </body> 
</html>

目前,我无法让它工作 :( 我上传了 imagesQueue 脚本并将其链接到页面,并将原始演示页面中的图像值替换为我的开发站点中的图像值。

最佳答案

你的想法很好,当你想在点击时有一个流畅的图像变化。虽然脚本是用纯 javascript 编码的(您可以使用更方便的方法:http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript),但它不应该对性能产生如此大的影响。 也许原因在别处。也许你的图片太重了……

除 javascript 之外的另一种解决方案是使用纯 CSS 方法,我想它会快得多。尝试将所有图像放在单个 PNG 上,并在 CSS 中尝试操纵各个选项卡的背景位置值。例如:

.tab {
    background-image:url('single.png');
}
#tab5 {
    background-position: 10px 20px;
}
#tab5:hover {
    background-position:10px 25px;
}

这样一来,所有图片都将一次加载一次。

关于javascript - 预加载图像的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6150070/

有关javascript - 预加载图像的最佳方式的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  5. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  6. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

  7. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  8. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

随机推荐