Автоматический предзагрузчик HTML - PullRequest
0 голосов
/ 09 июля 2010

У меня есть страница, которая будет загружать куски HTML, используя ajax.Все эти фрагменты будут иметь изображения, а некоторые из них будут указаны в отдельном CSS с использованием background-image.Я хотел написать предварительный загрузчик, чтобы загруженный кусок отображался только после завершения загрузки.Если бы все изображения были в HTML-чанке, я бы загрузил его, поместил в скрытый элемент, затем искал все теги img и контролировал, загружены ли они (или поместил несколько обратных вызовов в метод load).Проблема в CSS, я не могу сделать это так легко ... Поэтому единственный способ, который приходит мне в голову, - это иметь отдельный XML-файл со всеми местоположениями изображений и использовать его для создания элементов IMG, их загрузки и когда онизагружен дисплей чанка (поэтому изображения уже были извлечены с сервера).Знаете ли вы лучшие подходы?Есть ли готовые компоненты?

1 Ответ

1 голос
/ 09 июля 2010

Если вы принимаете совет, не делайте так. Приоритет здесь - содержание, изображения вторичны. Не позволяйте пользователю ждать контента из-за изображений. Это будет боль в заднице, особенно при медленных соединениях.

Лучше всего использовать изображения-заполнители / индикаторы для обратной связи с загружаемыми компонентами и, возможно, использовать эффект плавного затухания для изображений в тегах <img>.

Примечание: для небольших изображений вы можете попробовать Данные: URI , которые позволяют вставлять изображения в файлы HTML или CSS.


ОБНОВЛЕНО

Никогда не говори нет. :) Вот прототип того, что вы могли бы использовать. У меня он отлично работает в FF 3+ ​​и IE 5.5+, но по какой-то причине Chrome показывает, что cssRules равен нулю. Я должен выяснить, почему. Другим TODO является объединение правил @import в IE, так как он не работает тогда со стандартным набором правил.

В любом случае, как вы видите, вам нужно передать ему document, callback и есть необязательный аргумент timeout (по умолчанию 10 с).

callback будет выполняться после загрузки каждого изображения в документ. (обратите внимание, что в случае ошибки с 404 скрипт позаботится об этом). Здесь вы можете сделать свой FadeIn или шоу или что-то еще.

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);
}
...