【H5】手机浏览器分批次多张上传图片(文件),包含进度条

描述

本文所描述的上传文件主要是应用于手机端,PC端可以酌情改造。

应用场景:

手机浏览器一次上传多张图片或者文件,将文件每5个拆分为一组上传。上传进度条为手机端上传至后台所用时间不包含后台耗时。

选择图片用H5的input file标签(能否选多张看浏览器了),上传功能使用XMLHttpRequest后面简称xhr,jquery和zepto中都包含。

html

<span style="font-size:14px;"><div id="uploadBtn" class="needsclick"><span class="needsclick">上传照片</span></div>
<input type="file" id="uploadFile" name="uploadFile" multiple="multiple" accept="image/*" style="display: none"/></span>

1.将uploadBtn的点击事件绑定到file的点击事件上(这部分不多说),监听file的onchange事件获取上传的文件。

<span style="font-size:14px;">    var batchCount = 1;
    var batchNum = 5;
    var loadArr = [];
    $(function() {
        /**
         * file的onchange事件,处理上传完成后的数据
         */
        $('#uploadFile').on('change', function(){
            var files = $('#uploadFile').prop('files');
            var allFileCount = files.length;
            if(files.length == 0){
                return;
            }
            var fd;
            // 计算一共会分成几个批次
            batchCount = Math.ceil(allFileCount/batchNum);
            for(var i = 0;i < allFileCount; i++){
                if(i%batchNum == 0){
                    fd = new FormData();
                }
                if((i+1)%batchNum == 0 || (i+1) == allFileCount){
                    //监听事件
                    var xhr = new XMLHttpRequest();
                    if((i+1) == allFileCount){
                        var funNum = batchCount -1;
                    }else{
                        var funNum = (i- (batchNum -1))/batchNum;
                    }
                    <span style="color:#CC0000;">var c = "printFunName"+funNum; //根据不同的名字区分属于哪个批次(不能纯数字),否则批次会乱
                    eval("function "+c+"(evt){uploadProgress(evt);}");
                    xhr.upload.onprogress = eval(c);//绑定进度条事件</span>
                    xhr.onload = function(evt){ // 加载完成事件,包含502等结果需要判断状态
                        loadSuccess(evt);
                    };
                    xhr.onerror = function(){ // 加载error事件
                        loadError(evt);
                    }
                    //发送文件和表单自定义参数
                    xhr.open("POST", "/photo/uploadFile",true);// 设置请求地址,true表示异步,反之...

                    xhr.send(fd); // 发送请求
                }
            }
        });</span>
2.绑定各种事件,进度条最关键需要讲各个进程的进度累加  

<span style="font-size:14px;">    /**
     * 加载进度方法
     * @param evt
     */
    var progressArr = [];
    function uploadProgress(evt){
        if (evt.lengthComputable) {// 判断是否有进度
            <span style="color:#FF0000;">var funName = evt.currentTarget.onprogress.name; // 实在是没发传参了,只好用这个了,有好的方法可以留言
            var funIndex = funName.substr(12);// 截取方法名的字符串后的数字,用来判断是哪个批次的
            //evt.loaded:文件上传的大小 evt.total:文件总的大小
            var percentComplete = Math.round((evt.loaded / evt.total) * 100);
            progressArr[funIndex] = percentComplete; // 把当前进度放进一个数组里
            var prpgressTotal = 0;
            for(var i = 0; i < progressArr.length; i++){ // 遍历数组所有的进度,相加
                if(progressArr[i] != "" || progressArr[i] != undefined || progressArr[i] != 0){
                    prpgressTotal = prpgressTotal + progressArr[i];//一次上传图片分了4批这里相加的结果在0--400之间
                }
            }
            //加载进度条,同时显示信息,这个位置要除以批次数量,假如最大400除以4个批次就是100%,四舍五入小数点
            var str  = '' + Math.round(prpgressTotal / batchCount) + '%';
            // str就是一个百分比的字符串,自己展示出来即可
        }
    }</span>

 
4.进度条这是最大的难点,因为是异步的结果需要保证每个批次的进度不要乱,放到数组中这样每个批次只会有一个最大的进度数字。用方法名称开传递参数实属无奈,因为这里拿不到response。 ↑ 

<span style="color:#000000;">    /**
     * 上传文件成功事件
     */
    function loadSuccess(evt){
        var loadNum; //积累批次
        if(evt.target.status == 200){ // 200成功
            var jsonData = JSON.parse(evt.target.response); 
            loadNum = loadArr.push(jsonData);// 每次把response的数据保留,所有批次都到了一起处理,可以单独显示结果
           // 其中出现错误的请求要记录,要不后面不知道一种成功了几张,一个error表示一个批次都错误
            loadNum = loadArr.push("error");
        }
        if(loadNum == batchCount){ // 批次数等于完成的总数时就是所有数据都有结果了
            buildMessage(); // 自行处理loadArr中的结果,全局变量
        }
    }

 
 
 
 
5.处理返回结果主要是把error的问题处理好的就可以了,失败的监听事件跟成功的同理,不写了 ↑

总结

分批上传可以避免图片太多一次请求失败全失败的结果,而且速度也有提升,希望对大家有帮助。写的不对的地方请指正


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值