Доработка progress bar для хрома

И вот, я похвасталась, мол знаю как сделать полосу загрузки (prpogress bar) для загрузки файлов. Здесь написала себе заметку.
За основу использовала код на чистом javascript


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


Долго ли, коротко ли я мучилась над этим вопросом, но нашла ответ там же, где и нашла информацию об этом загрузчике. Тут, читая очень внимательно  jquery.uploadProgress.js . А здесь, я смотрела пример использования
Оказывается, что ajax запрос на получение данных количества загруженных байт, надо выполнять во фрейме.  Я смело взяла предлагаемый  код и начала использовать. Пришлось чуть поправить его. Получилось вот что


Строка 36
 if($.browser.safari && top.document == document) {
Заменила на 
 if($.browser.safari) {


И ещё у меня /progress - возвращал не json, поэтому строку  90 в топку
// dataType: options.dataType,

И строку 91 чуть поменяла
 success: function(upload) {
На
 success: function(data) { upload = eval(data);
И все. Сижу,.значит, тестирую, мол все кульно работает, уже опубликовала на реальной странице и прогоняю последние тесты, смакуя как оно все хорошо, но не долго было моё ликование

Но из-за этого кода, у меня чуть в другом месте запарка была, к тому же ещё через раз... тьфу..

Спасибо, руководителю. Я его позвала, взболтнула, что у меня тут наладила, там поехало. Он глянул в код, засрамил меня, мол какого черта используешь фигню, сама бы написала проще было бы в сто раз....  Так вот, потом легким движением руки наше страницу  по которой пояснил, что отправлять запросы надо в другом окне, нежели будет идти сама загрузка. Прстой эксперимент. Возвращаем мой самый первый код, добавляем в тег form target="_blank" и оп ля работает. Но так как нам новые окна не нужны, я уже дальше сама проработала механизм отправки запросов с каком-нибудь другом окне - фремйме.

И вот как оно получилось.
1 - Генерировать налету фрейм мне показалось муторно, поэтому я сразу в html вставила его.
 <iframe name="uplframe{{uuid}}" src="/uplframe.php" style="display:none;"></iframe>
{{uuid}} - это я так, на всякий пожарный дала уникальное имя Мы используем шаблонизатор, так вот это уникальная строка, cгенерированная в пxп, которую я подрисовываю в название фрейма


2 - на submit уже была повешана функция, в нее я и добавила 
$('#upload_form').bind('submit',function(e) { var self = $(this);
.....
var iframe = window.frames['uplframe{{uuid}}']; // наш фрейм var uuid = iframe.genUUID(); iframe.openProgressBar(uuid, progressFunc);
//корректируем action главным образом добавляя X-Progress-ID self.attr('action', 'http://' + upload_host + '/files'+'?X-Progress-ID=' + uuid); self.find('[name="location"]').val('http://'+host+'/contents/upload.php?fid=0&cid='+id+'&upd_tree=1'); $('#statusbar').show(); //отображаем полосу загрузки

});
//собственно функция рисующая полосу
function progressFunc(upload)
    {
       // alert('progressFunc'+upload.state);


        if(upload.state == 'uploading')
            document.getElementById('tp').innerHTML = 'Идет загрузка файла… ';//upload.state;
        else
            document.getElementById('tp').innerHTML = upload.state;




        if (upload.state == 'done' || upload.state == 'uploading') {
            bar = document.getElementById('progressbar');
            w = 400 * upload.received / upload.size;
            bar.style.width = parseInt( w ) + 'px';
        }


    }



 3 - Код полосы загрузки
<style> #statusbar { display: none; } </style>
<div id="statusbar"> <div><span id="fname"></span> <span id="tp">Подготовка к загрузке.....<span></div> <div id="progress" style="width: 400px; border: 1px solid black"> <div id="progressbar" style="width: 1px; background-color: black; border: 1px solid #4ccc2a;"> </div> </div> </div>

4 - Код страницы фрейма
<html>
<head>
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <script type="text/javascript">
        var interval = null;

        function genUUID(){
            var uuid = "";
            for (i = 0; i < 32; i++) {
                uuid += Math.floor(Math.random() * 16).toString(16);
            }
            return uuid;
        }

        function openProgressBar(uuid, __callback) {

            //создать фрейм налету и в нем делать аяксзапросы на /progress
            interval = window.setInterval(
                function () {
                    fetch(uuid,__callback);
                },
                1000
            );
        }

        function fetch(uuid,__callback) {
            var req = new XMLHttpRequest();
            req.open("GET", "/progress", 1);
            req.setRequestHeader("X-Progress-ID", uuid);
            req.onreadystatechange = function () {

                if (req.readyState == 4) {
                    if (req.status == 200) {
                        /* poor-man JSON parser */
                        var upload = eval(req.responseText);
                        /*if(upload.state == 'uploading')
                            document.getElementById('tp').innerHTML = 'Идет загрузка файла… ';//upload.state;
                        else
                            document.getElementById('tp').innerHTML = upload.state;


                        if (upload.state == 'done' || upload.state == 'uploading') {
                            bar = document.getElementById('progressbar');
                            w = 400 * upload.received / upload.size;
                            bar.style.width = parseInt( w ) + 'px';
                        }
                        */
                        if (upload.state == 'done') {
                            window.clearTimeout(interval);
                        }
                        __callback(upload);
                    }
                }
            }

            req.send(null);
        }
    </script>
</head><body></body></html>

Мне пора убегать, но это я использую и радуюсь.. пока....














Комментарии

Популярные сообщения