js 实现多图片上传,并且展示上传进度

最近项目需要做一个如下图所示的图片上传功能;


js 实现多图片上传,并且展示上传进度_第1张图片
image.png

找了很多插件发现都不是我自己想要的,索性自己实现一个,也可以学习一下;
主要的思想就是:
1.所有的图片包括相机图标的蓝色窗口(以下皆描述为相机)都看成一个li,点击相机选择文件上传;
2.读取到文件之后,循环在相机之前插入图片的li,具体的图片处理,见2-1至2-5
3.如果图片个数达到要求,隐藏相机;
4.删除图片,将对应的li remove掉即可,注意相机的隐藏和展示;

图片的读取以及上传原理:
2-1.使用输入框的file类型,进行图片的获取
2-2.使用FileReader进行文件的读取,并且转换成dataURL格式
2-3.采用canvas对图片进行剪裁,并且转成dataURL格式;
2-4.将dataURL数据转成bolb格式
2-5.将bolb添加到FormData中
2-6.使用XMLHttpRequest进行图片上传,可以查看进度;

以上就是一个完整的实现流程,如果不需要进行剪裁图片,直接原图上传,直接省略第2-3点;

1.使用input的多文件上传,设置好accept

 

2.使用FileReader读取文件
在这里遇到了一个问题,开始我在load中获取值是使用的reader.result,导致一直只能拿到最后一条数据;然后断点发现reader.load是异步执行的,在for循环结束之后才能顺序执行load方法,所以在load中获取url不可使用 reader.result,必须通过load函数的参数进行获取值

function selectImage(imgFile) {
    var allFile = imgFile.files;
    var imageArr = [];
    for(var i=0;i'+
                                ''+
                            '
'; document.getElementById("uploadUL").insertBefore(li, document.getElementById("uploadBtn")); }; } }

3.如果需要对图像进行剪裁再回显,加载页面的代码应该放入到这一步,按照你的需求去完成;
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
img 规定要使用的图像、画布或视频。
sx 可选。开始剪切的 x 坐标位置。
sy 可选。开始剪切的 y 坐标位置。
swidth 可选。被剪切图像的宽度。
sheight 可选。被剪切图像的高度。
x 在画布上放置图像的 x 坐标位置。
y 在画布上放置图像的 y 坐标位置。
width 可选。要使用的图像的宽度。(伸展或缩小图像)
height 可选。要使用的图像的高度。(伸展或缩小图像)
按照你自己的需求去剪裁,也可以不进行剪裁,按照实际大小去展示;不剪裁的完整写法如下

function canvasImg(dataURL) {
    const img = new window.Image();
    img.src = dataURL;
    var canvas = document.createElement("canvas"),
        ctx = canvas.getContext("2d");
    img.onload = function() { //图片加载完成
        //canvas 值按照你自己的实际需求去写
        canvas.width = 131;
        canvas.height = 131;
        ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
        document.getElementById("uploadUL").insertBefore(canvas, document.getElementById("uploadBtn"));
    };
}

将剪裁的图片转成dataURL格式

//图片的质量,这里设置的是1,也可以是小数
var quality = 1; 
//获取画布图片,并且要jpg格式
var data = canvas.toDataURL("image/jpeg", quality); 
data = data.split(',')[1];

4.将dataURL转成Blob

data = window.atob(data);
var ia = new Uint8Array(data.length);
for(var i = 0; i < data.length; i++) {
    ia[i] = data.charCodeAt(i);
}
//以上均为二进制参数处理,从而获取一个blob对象
var resultBolb = new Blob([ia], { 
    type: "image/jpeg"
});

5.上传图片

function fileUpload(resultBolb) { 
    var fd = new FormData(); 
    //向form中加入图片数据,name属性是file
    fd.append("file", resultBolb); 
    //上传图片
    var xhr = new XMLHttpRequest();
    //请求成功
    xhr.addEventListener('load', function(resUpload) {
    }, false);
    //请求失败
    xhr.addEventListener('error', function() {
    }, false);
    //上传终止
    xhr.addEventListener('abort', function() {
    }, false);
    //上传进度
    xhr.upload.addEventListener('progress', function() {
    }, false);
    xhr.open('POST', "http://XXXXXXXXXXXXX"); //请求地址
    xhr.send(fd); //发送
}

以上就是完成的js实现代码,以下简单展示一下实现的html+css:

以上并不是完成代码,后面整理一下把完整代码放出来;欢迎提意见哦:)

很多朋友私信我到底怎么实现我下面把完整版代码贴出来;
以下代码经过了简化,和上面教程不太一样,主要是为了配合后台传数据,如果想按照上面教程进行做肯定也是没有问题的
需要导入jquery包+我自己写的一个公共方法包(需要的私信我邮箱或者评论留邮箱,我不贴出来了,太长了)
我们后台提供的接口是多图片上传的,所以就在选择了图片之后点击按钮调用fileUpload,按钮被我整理这个demo出来的时候删掉了,你们自己加一个按钮吧,这个也不难的;




    
    
    
    
    
    



上传图片(最多4张)

---------------------------------------190102更新------------------------------------
代码放在了git,地址:https://github.com/super-jingjing/multipleUploadImage.git
不用给我留邮箱了哈,一直发邮件感觉有点麻烦

你可能感兴趣的:(js 实现多图片上传,并且展示上传进度)