自己的一套多图上传

多图上传在各个网站都是个很常见的功能,对于刚入门前端不久的新人来说,网上插件一大堆,随便拿来就能用是个正解。菜鸟的我喜欢折腾,闲来无事,自己写个玩玩。

先来复习几个小知识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FileReader:
FileReader主要用于将文件内容读入内存,通过一系列异步接口,可以在主线程中访问本地文件。
使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要处理的文件或数据。
创建实例:
var reader = new FileReader();

方法:
abort():void 终止文件读取操作
readAsArrayBuffer(file):void 异步按字节读取文件内容,结果用ArrayBuffer对象表示
readAsBinaryString(file):void 异步按字节读取文件内容,结果为文件的二进制串
readAsDataURL(file):void 异步读取文件内容,结果用data:url的字符串形式表示
readAsText(file,encoding):void 异步按字符读取文件内容,结果用字符串形式表示

事件:
onabort 当读取操作被中止时调用
onerror 当读取操作发生错误时调用
onload 当读取操作成功完成时调用
onloadend 当读取操作完成时调用,不管是成功还是失败
onloadstart 当读取操作将要开始之前调用
onprogress 在读取数据过程中周期性调用

有点神奇了,然后了解一下base64

1
2
3
百度百科上的解释
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。
Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,需要解码后才能阅读。

有点不知所云,简单来说,base64就是一大串不可读字符串,将图片文件直接转为base64,就可以将图片以文本的方式直接传给后台。

说说实现原理

有了上面的复习,多图片上传似乎有了点眉目。
1.用户每上传一次图片,就将这张图片转化为base64,放进数组
2.提交的时候把数组当做普通数据直接传到后台

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<style>
*{
padding:0;
margin:0;
}
body{
background:#eee;
}
.wrapper-upload{
width:500px;
height:400px;
margin: 100 auto;
box-shadow: 0 0 5px #ccc;
border-radius: 10px;
background-color: #fff;
position: relative;
overflow: hidden;
}
.wrapper-upload input[type=file]{
display: none;
}
.file-list ul{
list-style: none;
text-align: center;
margin-top:10px;
}
.file-list li{
width:130px;
height:100px;
display: inline-block;
overflow: hidden;
border-radius: 5px;
margin:5px;
box-shadow: 0 0 5px #000;
position:relative;
transition: all 1s ease;
}
.file-list li img.imgs{
height:100px;
}
.file-list li img.btn-del{
position:absolute;
left:50%;
top:0;
transform: translate(-50%,-50%);
width:30px;
opacity: 0;
transition: all .5s ease;
z-index: 3;
cursor: pointer;
}
.file-list li:hover img.imgs{
opacity: .6;
}
.file-list li:hover img.btn-del{
opacity: 1;
top:50%;
display: block;
}
.btn-upload{
position: absolute;
bottom:10px;
left:50%;
display: block;
padding: 0;
width: 90px;
height: 30px;
background-color: orange;
color: #fff;
font-size: 16px;
font-weight: 600;
text-align: center;
line-height: 30px;
border-radius: 3px;
transform: translate(-50%,0);
cursor: pointer;
}
</style>
<script>
$(function(){
Upload.init();
});
var Upload = {
init: function() {
this.eventChange();
this.deleteImg();
},
arrImg: [], // 已上传图片的base64组成数组
eventChange: function() {
var that = this;
$(document).on('change', '#upload', function(e) {
if (that.arrImg.length >= 9) {
alert('最多上传9张图片');
return false;
}
var reader = new FileReader();
var file = event.target.files[0];

// 存在图片就读取为base64
if (!file) {
alert('未选择任何图片');
}else{
reader.readAsDataURL(file);
}
// 当读取操作成功完成时将图片放进数组,然后遍历出图片
reader.onload = function (e) {
var imgBase64 = reader.result;
that.arrImg.push(imgBase64);
that.readerImg();
}
});
},
// 图片遍历到面板上
readerImg: function() {
var that = this;
var strHtml = '';
for (var i = 0; i < that.arrImg.length; i++) {
strHtml += '<li> <img src="./img/del.svg" data-index="' + i + '" class="btn-del" /> <img class="imgs" src="' + that.arrImg[i] + '"></li>';
}
$('.file-list ul').html(strHtml);
},
// 删除图片操作
deleteImg: function() {
var that = this;
$(document).on('click', '.btn-del', function(){
var index = $(this).attr('data-index');
that.arrImg.splice(index, 1);
that.readerImg();
});
}
};
</script>

预览一下

持续更新…