【问题标题】:Load all my images contained in only one DIV加载仅包含在一个 DIV 中的所有图像
【发布时间】:2012-01-04 05:44:54
【问题描述】:

我希望我的 HTML 页面能够正常加载,但我希望页面的某个部分仅在检索到该部分的所有图像(静态和翻转)后才完全加载。

我有这张使用图像地图和多边形创建的地图。当用户滚动到某个状态时,会加载一个全新的地图,但它会创建仅重新加载该地图的该部分的外观。我以前从未见过这样做,因为无法更改图像地图上的图像或颜色,所以我不得不这样做。

这里是页面链接:http://www.imaspy.com/unitedStatesMap.html

正如您所见,翻转图像需要一段时间才能加载到每个州...但是一旦它们全部加载完毕,地图就会完美运行。我希望在地图出现之前加载所有图像。我怎样才能用 JavaScript 做到这一点?

谢谢!

【问题讨论】:

  • 在网站上搜索 JavaScript Image preloader

标签: javascript jquery html css imagemap


【解决方案1】:

正如其他人已经指出的那样,通常的解决方案是预加载 mouseOver 图像。这是非常基本的,RobG's answer 应该可以正常工作。

但是,由于您有 每个 状态的 mouseOver 状态的 整个 地图的图像,这对访问者的带宽不是很友好。每个 222 KB,这相当于 (50 × 222) / 1024 ≈ 10.8 MB 只是为了加载网站。我会建议您找到其他解决方案。


更新:我想到了我提出的解决方案中的一个错误。解决方案及详情见答案末尾。


如果您想尽可能坚持当前的解决方案,我会这样做:

  • 保留基本图像和图像映射。
  • 为 mouseOver 状态创建单独的图像,但仅裁剪为状态本身(而不是整个地图)。
  • 找到每个 mouseOver 图像的 topleft 坐标(相对于 #mapContent div)并将它们保存在一种命名集合中(在 JavaScript 中,这只是一个普通的对象)。

那个对象(或命名的集合)可能看起来像这样:

var states = {
  'newMexico': {
    top:  400,
    left: 300
  },
  'arizona': {
    top:  350,
    left: 250
  },
};

您的预加载器可能如下所示:

function preloadStates() {
    var state, img;
  
    for (state in states) {
        img = new Image();
        img.src = '/image/' + state + '.png';
        states[state].img = $(img).css({
                    position: 'absolute',
                    top: states[state].top,
                    left: states[state].left
                });
    }
}

因为for .. in 枚举对象中的键,所以state 是键的名称(因此也是状态的名称)。我们将一个新的<img /> 对象(包装在一个jQuery 对象中)保存到state 集合中(这样我们以后可以访问它),然后我们将topleft 位置应用到它。

现在,在 mouseOver 上向用户显示这些预加载的图像:

var currentState = null;
var currentImage = null;

$("#imagemap area").hover(
    function () {
        var image;
        var state;
        
        currentState = $(this).attr("id");

        // Retrieve and show the preloaded Image:
        currentImage = states[currentState].img; // <-- wrapped in jQuery-object
        currentImage.appendTo('#mapContent');
    },
    function () {
        if (currentImage !== null) {
            currentImage.remove();
            currentImage = null;
        }
    }
);

这只是将预加载的图像附加到#mapContent div。不要忘记将#mapContentposition设置为relative,否则图像的位置将相对于文档,而不是#mapContent


更新

我只是想到了我提出的解决方案中的一个明显错误:

由于悬停图像将覆盖原始图像mouseOut 事件将在悬停图像显示后立即触发。在悬停图像而不是原始图像上监听 mouseOut 事件可以避免这种情况,但会产生一个矩形点击区域。

幸运的是,有一个简单的解决方案:在原始图像(和悬停图像)之上添加一个透明图像,然后将imagemap 应用到该图像上。

这是一个概念证明:http://jsfiddle.net/PPvG/t8prx/

几点建议:

  • 再次确保#mapContent 已定位(相对或绝对)。

  • 将透明图像绝对定位在top:0left:0 并使其与原始图像完全一样高和宽。

  • 确保透明图像的 z-index 至少为 1(并且高于悬停图像):

    #overlay { z-index: 1;位置:绝对;顶部:0;左:0; }

  • 通过将其设为1px transparent gif 或将其设为opacity: 0,使叠加层透明。前者更安全。

对于疏忽,我深表歉意。 :-)

【讨论】:

  • 除了闪存没有其他解决方案。只是对你先说的话发表评论。仍在阅读您的帖子。
  • 哇,工作量太大了。我明天必须去处理这个。谢谢
【解决方案2】:

预加载图片的常用方法是:

var preLoadedImages;

function preloadImages() {
  var img;
  var imageSources = ['01.jpg','02.jpg'];
  var i = imageSources.length;
  preLoadedImages = [];

  while (i--) {
    img = new Image();
    img.src = imageSources[i];
    preLoadedImages[i] = img;
  }
}

请注意,图像对象数组必须至少保持足够长的时间,以便加载(和缓存)所有图像,因此使用全局来存储它们。您也许可以改用闭包。这也为您提供了一个方便的图像集合及其在其他功能中使用的 src 属性(例如交换图像)。

如果您想在执行某项操作之前等待所有图像加载,您可以为每个图像创建一个标志,然后在每个图像上放置一个加载侦听器以取消其标志。当所有标志都被取消时,所有图像都被加载。

【讨论】:

  • @Michael:--decrement operator。所以i-- 返回i,然后将i 的值降低一。 while 循环将在 i &gt; 0 时运行,并在每次迭代时递减 i
【解决方案3】:

使用“图像”对象。应该是这样的:

<script type="text/javascript">
    var mouseoverImg = new Image(120, 90);
    mouseoverImg.src = "img2.gif";
    var mousedownImg = new Image(120, 90);
    mousedownImg.src = "img3.gif";
</script>

让我们假设文档中已经存在“img1.gif”。 img2.gif 在 mouseover 时显示,img3.gif 在 mousedown 时显示。您可以使用 addEventListener 或其他事件注册方式,就是这样。

好的,这里有一个更详细的例子,但我留给你微调它。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"  
"http://www.w3.org/TR/html4/strict.dtd">

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <title>The 'image' Object</title>

    <style type="text/css">
    <!--

    -->
    </style>


    <script type="text/javascript">
        var mouseoverImg = new Image(120, 90);
        mouseoverImg.src = "img2.gif";
        var mousedownImg = new Image(120, 90);
        mousedownImg.src = "img3.gif";
    </script>

</head>

<body>
    <h1>The 'image' Object</h1>

    <p>
        <img id="img01" src="img1.gif" width="120" height="90"  
title="image 1" alt="Image 1" />
    </p>

    <script type="text/javascript">

        var img01 = document.getElementById("img01");
        img01.addEventListener("mouseover", rolloverImg, false);
        img01.addEventListener("mouseout", rolloverImg, false);
        img01.addEventListener("mousedown", rolloverImg, false);

        var currentImg = "img1";

        function rolloverImg(e) {
            if (e.type == "mouseover") {
                img01.src = mouseoverImg.src;
            } else if (e.type == "mouseout") {
                img01.src = "img1.gif";
            } else if (e.type == "mousedown") {
                img01.src = mousedownImg.src;
            }           
        }

    </script>

</body>
</html>

您可以使用一些随机的类似按钮的图像,您可以从某个地方下载它们;确保它们被命名为“img1.gif”、“img2.gif”和“img3.gif”。这个例子只是一个演示。您需要根据自己的需要对其进行调整。

【讨论】:

  • 这如何帮助我更快地加载图像?这只是显示翻转图像的另一种方式。
  • 这样您可以加载在鼠标悬停和/或鼠标悬停时显示的附加图像以及页面的其余部分。在用户将鼠标移到目标图像上之前,这些附加图像不会显示,但一旦发生,它们就可以显示,即那时它不会去服务器加载图像。基本上,您在此处预加载图像。
  • 好的。我以前从未见过这个图像对象。如何将此应用于我的 HTML?你能稍微编辑一下代码,让我看看它到底是如何工作的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 2012-12-03
  • 2020-12-24
  • 2019-08-01
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多