Полученные байты и общее количество байтов изображений через Javascript / jQuery

Я работаю над предварительным загрузчиком изображений на основе Javascript / jQuery и наткнулся на небольшую загвоздку. Хотя на данный момент он обеспечивает прогресс на основе loaded_images / total_images, это не очень точно, учитывая, что на странице может быть тысяча изображений размером 1 КБ и одно изображение размером 1 МБ.

Я ищу способ включить размер файла в расчет прогресса. Теперь я изучил некоторые (кроссбраузерные) уловки для захвата размера файла данного изображения, и мне кажется, что запросы Ajax для Content-Length были самыми надежными (с точки зрения точности):

var imageSizeTotal = 0;
var ajaxReqest = $.ajax({
    type: 'HEAD',
    url: 'path/to/image',
    success: function(message){
        imageSizeTotal += parseInt(ajaxRequest.getResponseHeader('Content-Length'));
    }
});

Теперь я считаю этот метод весьма полезным, поскольку я могу предоставить сообщение о состоянии Инициализация во время выполнения необходимых запросов. Однако сейчас у меня двоякая проблема:

  1. Есть ли способ захватить байты, загруженные данным объектом изображения, возможно, используя setInterval() для периодической проверки? В противном случае я как бы вернулся к проблеме зависания индикатора выполнения на больших файлах.
  2. Как я могу заставить калькулятор фактического прогресса и т. Д. Часть скрипта ждать, пока не будут выполнены необходимые запросы Ajax (отобразить Initializing или что-то еще), чтобы он мог продолжить загрузку?

Кроме того, вот сценарий, который я использую в настоящее время, который, опять же, вычисляет прогресс на основе количества изображений, независимо от размера файла или полученных байтов.

var preloaderTotal = 0;
var preloaderLoaded = 0;
var preloaderCurrent = null;

$('#preloaderCurtain')
    .bind('preloaderStart', function(){
        $(this)
            .show();
        $('*')
            .filter(function(e){
                if($(this).css('background-image') != 'none'){
                    preloaderTotal++;
                    return true;
                }
            })
            .each(function(index){
                preloaderCurrent = new Image();
                preloaderCurrent.src = $(this).css('background-image').slice(5, -2);
                preloaderCurrent.onload = function(e){
                    preloaderLoaded++;
                    if(preloaderLoaded == preloaderTotal - 1){
                        $('#preloaderCurtain')
                            .trigger('preloaderComplete')
                    }
                    $('#preloaderCurtain')
                        .trigger('preloaderProgress')
                };
            });
    })
    .bind('preloaderComplete', function(){
        $(this)
            .fadeOut(500)
        startAnimation();
    })
    .bind('preloaderProgress', function(e){
        $('#preloaderProgress')
            .css('opacity', 0.25 + (preloaderLoaded / preloaderTotal))
            .text(Math.floor((preloaderLoaded / preloaderTotal) * 100) + '%');
    })
    .trigger('preloaderStart');

Надеюсь, я смогу превратить это в плагин, как только исправлю в нем ошибки.


person Dan Lugg    schedule 16.01.2011    source источник
comment
Я не знаю ни одного способа получить размер частично загруженного изображения   -  person mplungjan    schedule 17.01.2011
comment
Я не могу себе представить, чтобы эта работа работала без помощи на стороне сервера - в частности, чего-то, что могло бы предоставить имя (URL) изображения для сопоставления таблицы с размером изображения. Теперь, даже с этим, вы не сможете узнать, какая часть каждого изображения загружена, но ваши обработчики нагрузки на объекты Image могут, по крайней мере, знать, когда они готовы, и отметить размер.   -  person Pointy    schedule 17.01.2011
comment
@mplugjan; Спасибо, я заметил вашу историю с Javascript, и, к сожалению, вы не знаете способа. Я уже согласился с тем, что это, скорее всего, невозможно, но во второй части моего вопроса мне все же нужна помощь.   -  person Dan Lugg    schedule 17.01.2011
comment
@Pointy; Я полагаю, это то, что мне нужно сделать. Это даст более точную индикацию прогресса, но индикатор все равно будет зависать на больших изображениях, чего я надеялся избежать.   -  person Dan Lugg    schedule 17.01.2011
comment
Удивительное количество индикаторов прогресса - подделка. На самом деле они не указывают на истинный прогресс. Вы можете поддерживать прогресс, оценивая. Цель состоит в том, чтобы держать пользователя занятым, а не информировать его об идеальном проценте прогресса.   -  person goat    schedule 17.01.2011
comment
Хм - размер у вас есть. Можете ли вы загрузить несколько изображений меньшего размера и увидеть приблизительное время загрузки и применить это к более крупным изображениям - эта приблизительная оценка может быть достаточно хорошей для индикатора выполнения - вы можете пересчитать бит / с для каждого полученного изображения ... Я только думаю вслух здесь ...   -  person mplungjan    schedule 17.01.2011
comment
@chris; Верно, однако, чтобы проверить свои способности и обеспечить как можно более точную индикацию прогресса, я хотел бы исчерпать все варианты в своей попытке выполнить эту работу. @mplungjan; Мне нравится эта идея, это было еще одно соображение, которое я сделал, заказав массив изображений для загрузки по их размеру файла (по возрастанию), а затем, обманув математику, я мог обеспечить несколько точную индикацию, когда он попадает в более крупные изображения. Мой тестовый пример представляет собой одну страницу с ~ 150 изображениями размером от ~ 1 КБ до ~ 1,5 МБ.   -  person Dan Lugg    schedule 17.01.2011
comment
Есть ли какие-либо мысли по поводу моей второй проблемы - обеспечения выполнения запросов размера? Я думаю о проверках, основанных на setInterval() завершении массива файлов. После заполнения начните предварительную нагрузку.   -  person Dan Lugg    schedule 17.01.2011
comment
Мне кажется, что к тому времени, когда у вас будет Content-Length через обработчик успеха, все данные изображения уже загружены. Эта информация нужна вам до загрузки изображения ...   -  person Hemlock    schedule 17.01.2011
comment
@Hemlock; Однако запрос заголовка не извлекает контент, он только захватывает метаданные, верно? Если у меня есть 20 изображений на данной странице, в среднем 250 КБ, при 5 МБ, надеюсь, 20 запросов заголовка будут быстрее, чем фактическая передача данных ...   -  person Dan Lugg    schedule 17.01.2011


Ответы (1)


Похоже, здесь был задан аналогичный вопрос и дан ответ:

XmlHttpRequest.responseText при загрузке (readyState == 3) в Chrome

и тут:

Comet Jetty / Tomcat, проблемы с браузером с Firefox и Chrome

В основном - .responseText.length для Firefox и iPhone, .responseBody.length для IE, WebSockets для Chrome.

Второй поток предлагает Bayeux / dojo инкапсулировать все это для вас в API более высокого уровня, чтобы вам не приходилось писать это самостоятельно.

person Chris Moschini    schedule 18.01.2011
comment
Приятно :) Спас мой день! - person Sidius; 04.12.2015