0

我正在显示一些缩略图,这些缩略图会定期由服务器上的外部进程重新生成。我想在页面加载时在当前缺少的那些上显示一个微调器(gif),并在它们最终到达时用它们的缩略图替换微调器。显示微调器是微不足道的。缩略图文件名都是预先知道的。我还没有找到一种方法来观察它们是否出现在 Javascript 中。

可能需要几分钟才能创建一些缩略图。创建它们的过程会在执行新处理之前删除它们,从而产生新的缩略图。这些外部处理事件之间的间隔可以是几小时。

谁能想到一种方法来做到这一点?(没有 Ajax 或 Jquery - 只是基本的 Javascript)。

谢谢。

编辑- 我确信这可以改进,但它似乎工作。感谢您的提示和建议。它给了我我正在寻找的想法。有能力这样做的人可能希望删除顶部关于此问题已通过链接回答的注释 - 该问题不相关。--JKC

var intervalId, thumbs;

function refresh_thumbs() {
    // Refresh whether they need it or not. If the thumb isn't there,
    // onerror will (re)load the spinner. 
    for (i=0; i<thumbs.length; i++) {
        id = "snap_"+i;
        document.getElementById(id).src = thumbs[i];
    }
}

function init(thumbstring) {
    // Split comma-separated string into an array of thumbnail links
    thumbs=thumbstring.split(",");
    refresh_thumbs();
    intervalId = window.setInterval( refresh_thumbs, 5000); // milliseconds
}

例如,可能会生成一个包含以下内容的页面:

<img src='/d/thumb_0.png' id='snap_0' onerror='this.src="/s/spinner.gif";'>
<img src='/d/thumb_1.png' id='snap_1' onerror='this.src="/s/spinner.gif";'>

<script>
    init("/d/thumb_0.png,/d/thumb_1.png");
</script> 

refresh_thumbs之前调用setInterval是必要的,以防止必须等待 5 秒钟才能看到开始的拇指。

我怀疑出于任何原因我不需要保存的 intervalId。

4

2 回答 2

1

用于setInterval定期更改src正在等待的图像。您可以将查询字符串以时间戳的形式附加到图像 URL 以防止缓存。不确定如何以这种方式检测图像是否准备好,但我相信通过一些试验和错误很容易弄清楚。

更新:onerror为您设置的每个无法访问的 URL 触发。继续使用新的时间戳轮询 URL,直到您停止接收错误(这意味着图像已准备好)。

更新:我试图找到一个通用的解决方案来解决这个问题。这是我想出的:

HTML:

<body style="background-color: #CCC;">
    <img src="/img/fail.png" width=200 onerror="imgErr(this);" />
    <img src="/img/fail.png" width=200 onerror="imgErr(this);" />
    <img src="/img/fail.png" width=200 onerror="imgErr(this);" />
    <img src="/img/fail.png" width=200 onerror="imgErr(this);" />
    <img src="/img/fail.png" width=200 onerror="imgErr(this);" />
    <img src="/img/fail.png" width=200 onerror="imgErr(this);" />
</body>

JS:

var imgElems = [],
    imgUrls = [];

function imgErr(img) {
    imgElems.push(img);
    //imgUrls.push(img.src); // <-- real code
    imgUrls.push('/img/logo.png'); // <-- literal url for testing
}

onload = function () {
    var interval,
        timeout = 3000,
        time,
        url,
        img;

    interval = setInterval(function () {
        time = new Date().getTime();
        while (imgElems.length) {
            img = imgElems.shift();
            url = imgUrls.shift();
            img.src = url + '?time=' + time;
        }
    }, timeout);
}

JSFiddle

于 2013-08-29T22:21:47.887 回答
0

如果我理解正确,您的问题是不知道图像何时加载;您的问题是您无法发出图像请求,因为加载可能需要数小时。因此,当您设置 src 时,它会超时,这就是您获得的所有信息。

你有几个选择。

也许获取文件的最简单方法是不断尝试重新加载每个图像。在这种情况下,您已经接近了,尽管您希望在等待时显示一个带有微调器的单独 div:

<img src='spinner.gif' id='spinner' />
<img src='thumb.png' id='thumb' />

document.getElementById("thumb").onload = function() {
    document.getElementById("spinner").style[display] = "hidden";
}
document.getElementById("thumb").onerror = function() {
    this.src = "thumb.png";
}

您需要调整位置,但这会制作一个微调器,使其在图像加载时消失,并在图像尚未准备好时尝试重新加载它。

Jo Are By 已经建议了我要建议的另一种选择 - 每隔几分钟设置一个间隔来重置图像的来源。你可以在这里做很多变化(重置所有源,或者只重置失败的源,例如),但基本上,在你的文件末尾,你会想要这样的东西:

var intervalId = window.setInterval( function() {
    var elem = document.getElementById("thumb");
    // set the source twice, since I dont' see anywhere in the spec if setting 
    // the src to itself forces a reload.  
    var src = elem.src;
    elem.src = "http://foofoofoofoofoo.bar.bar";
    elem.src = src;
}, 300000); // set to every 5 minutes (300 seconds * 1000 milliseconds)

在那里的某个地方,您需要跟踪仍有多少未决,当它达到 0 时,调用window.clearInterval(intervalId);.

于 2013-08-29T22:39:07.853 回答