5

我正在使用 JavaScript 在 HTML 页面上创建一个基本的图形时钟显示。我正在使用标准 DOM 机制更新数字图形(每个数字仅在必要时更新):

digitOne.src = "file/path/one.png";

时钟工作正常,但我想知道每次更改 src 属性时所有或某些浏览器是否会盲目地从我的站点获取图像,而不是在 RAM 中缓存副本。我担心在某些情况下,也许在旧版浏览器中,查看图形时钟会不断产生数据流量并消耗我每月的数据限额。

所以我希望有人能告诉我这是否有风险,或者指出一种在 JavaScript 中交换图形的机制,它保证了现有图像将从内存中使用,而不是每次都触发网络获取。

(我一直在寻找一个明确的答案,但找不到一个。自 1999/2000 年以来,我没有将 JavaScript 用于 DHTML,所以我有点落伍了。至少不再需要编写每个 JavaScript 函数的两个版本,一个用于 IE4/5,一个用于 Netscape 4。)

4

4 回答 4

3

您不必担心交通问题。初始化应用程序时很容易缓存图像。在以下 JSFiddle 中查看我的示例:http: //jsfiddle.net/pAwdC/。当我初始化我正在调用的应用程序时loadImagesimg此方法为每个数字创建DOM 元素。它src是从数组中取出的imagesSrc。调用该loadImages函数时,浏览器向服务器发出少量 HTTP get 请求:

在此处输入图像描述

实际上,每个请求都是在以下情况下发出的:

current.src = imagesSrc[i];

被执行。

加载图像后,我只是将它们隐藏起来。当图像带有display: nonevisibility: hidden用户实际上看不到它们,但是当您使这些隐藏元素可见时,不再发出请求,只有最终的重绘、重排/重布局、重新样式由浏览器完成。仅在需要时才缓存和显示所有元素。您可以检查您的萤火虫或您正在使用的任何其他开发工具,以确保不再请求这些图像。

这是我的示例中的代码:

var images = [],
    imagesSrc = ['https://lh3.ggpht.com/-107YXK-eAXs/UB6V49H9yuI/AAAAAAAACsY/69ceZJXaYZE/s1600/number-one-.png',
    'https://lh3.ggpht.com/-8rOrxAwDl48/Txf99Sus18I/AAAAAAAAL1w/VcmeP7rNFwY/s1600/number2c.png',
    'https://lh3.ggpht.com/-aGatHUidcGw/UG6Oh2HdWXI/AAAAAAAADQY/yc1CTC7cpOY/s1600/number3.png'];

function loadImages() {
    var current;
    for (var i = 0; i < imagesSrc.length; i += 1) {
        current = document.createElement('img');
        current.src = imagesSrc[i];
        images.push(current);
        current.style.display = 'none';
        document.body.appendChild(current);
    }
}

function showImage() {
    var current = showImage.current || 0;
    if (current >= 3) {
        current = 0;
    }
    hideImages();
    images[current].style.display = 'block';
    current += 1;
    showImage.current = current;
    setTimeout(function () {
        showImage();
    }, 1000);
}

function hideImages() {
    for (var i = 0; i < images.length; i += 1) {
        images[i].style.display = 'none';
    }
}

loadImages();
showImage();

对于我的示例,我只需要每个数字的一​​个实例。当然,对于您的时钟,您可以img为每个数字创建四个实例(四个 DOM 元素),以便显示重复项。

对于您的应用程序,更好的方法可能是按需加载图像,但只加载一次然后缓存它们。这样做很好,因为用户可能不会停留在您的页面上查看每个数字(从 0 到 9),并且您可以通过这种延迟加载稍微提高性能。对于这种策略,您可以检查享元模式。它的主要思想是管理一组可重用的小对象并按需使用它们,同时控制它的创建。这是一个显示模式结构的 UML 类图:

在此处输入图像描述

我提到的方法有不同的变体。您可以做的最轻的变化可能是使用包含所有数字的单个图像。之后,您可以创建具有数字大小的不同元素(例如 div)。当您为这些元素设置具有特定位置的背景时,您可以通过仅加载单个图像来创建所有数字。这会将您的请求从 10 个减少到一个。例如,Facebook 有效地使用了这种方法。

如果您需要进一步的帮助,我很乐意提供帮助。​</p>

于 2012-11-18T16:04:38.463 回答
1

如果启用了 CSS,则以下模式有效。我提出这个是因为如果不是,它比解决方案更清晰一些。

<div id='clock'>
  <div id='digit0' style="display:block"><!-- ... --></div>
  <div id='digit1' style="display:none"><!-- ... --></div>
  <div id='digit2' style="display:none"><!-- ... --></div>
  <!-- ... -->
</div>

要更改数字显示,请隐藏当前可见的数字并使下一个可见。仅 JavaScript 的解决方案是相关的。使单个不可见<div>以隐藏不可见的数字。添加和删​​除单个数字<div>元素,将时钟显示中的旧数字与数字仓库元素中的下一个数字交换。

这两种解决方案都有这样的行为,即 DOM 子树中的图像只获取一次,因为子树永远不会被删除。

于 2012-11-18T15:55:48.247 回答
1

我建议您使用 HTML5 画布 2D 绘图。它根本不需要任何图像,目前所有浏览器的所有较新版本都支持它,即使在 IE 中也是如此。看一下这个

http://www.neilwallis.com/projects/html5/clock/index.php

阅读这个简单但很棒的教程:

http://diveintohtml5.info/canvas.html

于 2012-11-19T18:55:01.450 回答
0

如果您想绝对确定,您可以生成带有数字图像的 HTML 元素并将其放置到带有 的页面display: none,因此它已经加载并在页面上。

如果需要数字,您首先检查页面上的 HTML 元素并获取这个元素,将其设置为display: block或任何您需要的元素,然后用该元素替换当前的数字元素。

作为一些示例代码,我只是把它放在一起。

var digit_images = ["file/path/one.png", "file/path/two.png", "file/path/three.png", ...];

function giveMeTheDigit(digit)
{
    var img = digit_images[digit];
    var element = $("#digit_holder" + digit);

    if (element.length == 1)
    {
        $(".digit_holder").hide(); //hide the current holder
        element.show(); //show the new one
    }
    else
    {
        $('<div class="digit_holder" id="digit_holder' + digit + '"><img src="' + img + '" /></div>')
            .appendTo("#yourDestination");
    }
}

此代码未经测试,但我想您知道我在追求什么,并且可以根据您的需要对其进行编辑。祝你好运!

于 2012-11-18T15:51:30.210 回答