0

我有一个页面将使用 ajax 加载 HTML 块。所有这些片段都会有图像,其中一些将使用 background-image 在单独的 CSS 中指定。我想写一个预加载器,以便加载的块只有在所有加载完成后才会显示。如果所有图像都在 HTML 块中,我将加载它,将其放入隐藏元素中,然后查找所有 img 标签并控制它们是否已加载(或在加载方法中放置一些回调)。问题是 CSS 我不能那么容易地做到这一点......所以我想到的唯一方法是拥有一个包含所有图像位置的单独 xml 文件,并使用它来创建 IMG 元素,加载它们以及何时加载它们加载显示块(因此图像已经从服务器中提取)。你知道更好的方法吗?有没有现成的组件?

4

1 回答 1

1

如果您接受一条建议,请不要这样做。这里的优先级是内容,图像是次要的。不要因为图像而让用户等待内容。这将是一件令人头疼的事情,尤其是在连接速度较慢的情况下。

最好的办法是使用一些占位符/指示符图像来提供有关加载组件的反馈,并且可能对<img>标签中的图像使用一些不错的淡入淡出效果。

注意:对于小图像,您可以尝试Data: URIs,它允许您将图像嵌入到 HTML 或 CSS 文件中。


更新

永远不要说不。:) 这是您可以使用的原型。它适用于我在 FF 3+​​ 和 IE 5.5+ 中,但由于某种原因,Chrome 显示 cssRules 为空。我必须弄清楚为什么。另一个 TODO 是在 IE 中合并@import-ed 规则,因为它不适用于标准规则集。

无论如何,如您所见,您需要传递它 a document, acallback并且有一个可选 timeout参数(默认为 10s)。

callback在文档中加载每个图像后执行。(请注意,如果它因 404 失败,脚本会处理它)。在这里你可以做你的淡入或显示或其他东西。

存在作为后备,如果出现timeout任何问题,它无论如何都会在一定时间后调用回调。

// this function will execute a callback after all
// images has been loaded in a document
function imageLoader(document, callback, timeout) {

    timeout = timeout || 10000; // 10s default
    var i, j, remaining = 0;    // number of loading images
    // hash table to ensure uniqueness
    // url => image object
    var imgs = {};

    function handler(el, event) {
        remaining -= 1;
        if (remaining == 0 && !callback.done
         && typeof callback === "function") {
            callback.done = true;
            callback();
        }
    }

    // adds the image to the hash table
    function addImage(src, img) {
        if (!imgs[src]) {
          remaining++;
          img = img || new Image();
          img.onload  = handler;
          img.onerror = handler;
          img.src = img.src || src;
          // add to the hash table
          imgs[src] = img;
        }
    }

    // now gather all those images
    var sheets = document.styleSheets;
    for (i=0; i<sheets.length; i++) {

        // HTML <img> tags
        var els = document.getElementsByTagName("IMG");
        for (i=0; i<els.length; i++) {
            var el = els[i].src;
            addImage(el.src, el);
        }

        // CSS background images
        var css = sheets[i];
        var pos = css.href.lastIndexOf("/");
        var cssDir = (pos != -1) ? css.href.substring(0, pos + 1) : "";
        var rules  = css.cssRules || css.rules;

        for (j=0; j<rules.length; j++) {
            var style = rules[j].style;
            var img = style.backgroundImage;
            if (img == "none") img = "";
            var filename = img.substring(4, img.length - 1).replace(/['"]/g,"");
            if (filename) {
                if (filename.indexOf("http://") != 0
                 && filename.indexOf("/") != 0) {
                    filename = cssDir + filename;
                }
                addImage(filename);
            }
        }
    }

    // correct the start time
    var start = +new Date();

    var timer = setInterval(function(){
        var elapsed = +new Date() - start;
        // if timout reached and callback
        // hasn't been not called yet
        if (elapsed > timeout && !callback.done) {
            callback();
            callback.done = true;
            clearInterval(timer);
        }
    }, 50);
}
于 2010-07-09T09:10:27.137 回答