HTML5按顺序拖放上传

时间:2014-01-11 11:50:36

标签: javascript php html5 drag-and-drop

我有一个网络应用,我正在使用HTML5拖放上传。这是我第一次使用这项技术,所以我进行了一些研究,找到了一个简单的脚本,使其发挥作用。

一切正常,但我需要脚本不要一次上传所有文件,而是对每个文件发出单独的请求并按顺序上传(我在这里使用了正确的词吗?)。

有办法做到这一点吗?

由于

P.S。我使用PHP作为服务器端语言(并不是说它会对这个问题产生任何影响)

1 个答案:

答案 0 :(得分:1)

这是我前段时间偶然发现的一些代码的变体,作为使用DND api和进度条的实验。希望能帮助到你。您正在寻找的核心功能是ajaxSingleFileUploadhandleFileSelect

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <style type="text/css">
            .dropZone {
                position: relative;
                width: 200px;
                height: 200px;
                border-radius: 10px;
                line-height: 200px;
                text-align: center;
                border: dotted 1px gray;
            }
            .dropZoneHover {
                background: gray;
                box-shadow: inset 1px 1px 5px gray;
            }
            .jsProgressBar{
                border:solid 1px rgba(0,0,0,0.3);
                height: 1em;
                border-radius: 1em;
            }
            .jsProgress{
                background-image: linear-gradient(90deg, rgba(255,0,0,0.5), rgba(0,255,0,0.5));
                border-radius: 1em;
            }
        </style>
    </head>
    <body>
    <div id="drop_zone" class="dropZone">Drop files here</div>
    <output id="list"></output>

    <script>
        var $id = function (id) {return document.getElementById(id)};
        Element.prototype.on = Element.prototype.addEventListener;
        CSSStyleDeclaration.prototype.add=function(css){
            var tmpCSS = this.cssText;
            if(typeof css == 'object'){
                for(var o in css){
                    if(Object.prototype.hasOwnProperty.call(css,o)){
                        tmpCSS+=';'+o+':'+css[o]+';';
                    }
                }
            }
            else if(typeof css=='string'){
                tmpCSS+=';'+css+';';
            }
            tmpCSS.replace(/;;;/gi,';').replace(/;;/gi,';');
            this.cssText=tmpCSS;
        };
        Event.prototype.stop = function () {
            this.stopPropagation();
            this.preventDefault();
        };

        function changePercent(progressBar,val){ $id(progressBar).value(val); }

        function ProgressBar(el,width){
            el=$id(el);
            el.classList.add("jsProgressBar");
            var p=document.createElement('div');
            var t=document.createElement('div');
            var fh= Math.round(el.clientHeight*0.9)+'px';
            el.style.add({
                             display: 'inline-block',
                             'box-shadow': 'inset 0 0 5px rgba(0,0,0,0.2)',
                             position: 'relative',
                             padding:0,
                             margin: '0 auto'
                         });
            p.classList.add("jsProgress");
            p.style.add({width:'0',height:'100%'});

            t.style.add({width:'100%','text-align':'center',position:'absolute',top:0,bottom:0,left:0,'font-size':fh,'line-height':(el.clientHeight+'px'),'font-weight':'bold'});

            el.appendChild(p);
            el.appendChild(t);
            el.value=function(val){
                if(typeof val != 'undefined'){
                    val=(val>100)?100:(val<0)?0:val;
                    p.style.width=val+'%';
                    t.innerHTML=(val==0)?'':val+'%';
                    return el;
                }
                return t.innerHTML.replace(/%/g,'');
            };
            return el;
        }
        function _progressCallback(progressBar){
            return function(evt){
                var percent=(evt.loaded/evt.total *100);
                changePercent(progressBar, Math.round(percent));
                //$id('status').innerHTML = Math.round(percent)+'% uploaded... pleas wait';
            }
        }

        function ajaxSingleFileUpload(url, fileData, successCallback, failCallback, progressCallback, abortCallback) {
            var ajax = new XMLHttpRequest(), boundary = "FileUpload" + btoa("" + (Math.random()));
            ajax.open('POST', url);
            ajax.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
            var blob = fileData.blob;//atob(fileData.blob.split(',')[1]);
            var multipartHeader = ['--' ,
                               boundary ,
                               '\r\nContent-Disposition: form-data; name="file"; filename="' ,
                               fileData.name ,
                               '"\r\nContent-Type: ',
                               fileData.fileType,
                               '\r\n\r\n'].join('');
            var multipartTrailer = ['\r\n--', boundary , '--\r\n'].join('');
            var iaHeader = new Uint8Array(multipartHeader.length);
            for (var c = 0, l = multipartHeader.length; c < l; c++) {
                iaHeader[c] = multipartHeader.charCodeAt(c);
            }
            multipartHeader=iaHeader;

            if(!!progressCallback){ajax.upload.addEventListener('progress',progressCallback,false);}
            if(!!successCallback){ajax.addEventListener('load',successCallback,false);}
            if(!!failCallback){ajax.addEventListener('error',failCallback,false);}
            if(!!abortCallback){ajax.addEventListener('abort',abortCallback,false);}
            ajax.send(new Blob([multipartHeader,blob,multipartTrailer]));
        }

        function handleFileSelect(evt) {
            evt.stop();
            var files = evt.dataTransfer.files; // FileList object.
            // files is a FileList of File objects. List some properties.
            var output=[];
            for (var i = 0, f; f = files[i]; i++) {
                var fileReader = new FileReader();
                fileReader.onload = (function (theFile, id) {
                    return function (e) {
                        var fileData = e.target.result,
                                xFile = {
                                    name:     theFile.name,
                                    fileType: theFile.type,
                                    blob:     fileData
                                };
                        ajaxSingleFileUpload('fileUpload.php', xFile,undefined,undefined,_progressCallback('progress'+id));
                        var img = document.createElement('img');
                        img.title = theFile.name;
                        img.id = 'thumb' + id;
                        img.src = fileData;
                        if (img.width > img.height) {
                            img.style.width = (img.width > 60 ? '60' : img.width) + 'px';
                        }
                        else {
                            img.style.height = (img.height > 60 ? '60' : img.height) + 'px';
                        }
                        $id('list').insertBefore(img, null);
                    }
                })(f, i);

                fileReader.readAsArrayBuffer(f);
                output.push('<div><strong>', f.name, '</strong> (', f.type || 'n/a', ') - ',
                            f.size, ' bytes, last modified: ',
                            f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
                            '</div><div id="progress'+i+'" style="width:200px;height:15px;"></div>');
            }
            document.getElementById('list').innerHTML = output.join('');
            for(i=0;i<files.length;i++){
                ProgressBar('progress'+i);
            }
        }

        function handleDragOver(evt) {
            evt.stop();
            evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
        }
        var dropZone = $id('drop_zone');

        function handleDragOver2(evt) {
            dropZone.classList.add('dropZoneHover');
        }
        function handleDragLeave2(evt) {
            dropZone.classList.remove('dropZoneHover');
        }

        // Setup the dnd listeners.
        dropZone.on('dragover', handleDragOver, false);
        dropZone.on('dragover', handleDragOver2, false);
        dropZone.on('dragleave', handleDragLeave2, false);
        dropZone.on('drop', handleFileSelect, false);
        dropZone.on('drop', handleDragLeave2, false);
    </script>

    </body>
    </html>

对于PHP方面(您必须使用您想要的路径修改testUploads):

    <?php
    $fileName=$_FILES['file']['name'];
    $fileTmpLoc=$_FILES['file']['tmp_name'];
    $fileType=$_FILES['file']['type'];
    $fileSize=$_FILES['file']['error'];

    if(!$fileTmpLoc){
      //file not chosen
      echo 'Error: Please browse for a file before clicking the upload button.';
      exit();
    }

    if(move_uploaded_file($fileTmpLoc,"testUploads/$fileName")){
      echo "$fileName upload is complete.";
    }
    else{
      echo "Unable to save the file on the server.";
    }