这两天用原生徒手撸了个插件,写的不是很完美,在这里先介绍一下传统的面向过程的javascript写法,还有很多不足,希望多多指正
//onchange只有在文件发生改动的时候会调用
inputFile.onchange = function(){
progress = {value:0,count:this.files.length};
for (var i = 0; i < this.files.length; i++)readerFile(this.files,i);
}
function readerFile(files,index){
var reader = new FileReader();
var currFile =files[index];
reader.readAsDataURL(currFile);
if(checkFile(currFile,5)){
reader.onload = function(e){
currFile.result = e.target.result;
fileData.push({ //格式整理
name:currFile.name,
type:currFile.type,
size:currFile.size,
lastModified:currFile.lastModified,
result:currFile.result
});
createDOM(currFile)
progress.value+=1;
var num = progress.value/progress.count*100;
if(progress.value>=progress.count){
console.log(fileData.length+'个文件已全部读取完成!');
}
}
reader.onerror = function(){
console.log("文件上传失败!");
}
}
}
uploadBtn.onclick = function(){
formData = new FormData(formDom);
formData.set("files",JSON.stringify(fileData));
console.log(formData)
//封装完成 暂无接口测试
ajax({
url:"",
type:"POST",
data:formData,
success:function(){
console.log("上传成功")
},
error:function(){
console.log("上传失败")
}
})
}
function checkFile(currFile,max){
var isLegal = true;
if(['image/png','image/jpeg','image/jpg','image/gif'].indexOf(currFile.type)==-1){
console.log('文件类型只允许:png、jpg、gif');
isLegal = false;
}
if(currFile.size > 2048*1024){
console.log('文件大小超出限制,最大允许 2 MB');
isLegal = false;
}
if(fileExists(currFile.name+currFile.lastModified)){
console.log(currFile.name+",文件重复");
isLegal = false;
}
if(fileData.length>=max){
console.log('文件数量超出,最多上传'+max+'张图片');
isLegal = false;
}
return isLegal;
}
function fileExists(checkFlag){
var isRepeat = false;
console.log(fileData)
fileData.forEach(function(f){
if(f.name + f.lastModified === checkFlag)isRepeat = true;
});
return isRepeat;
}
我这里是为了更直观地看到上传效果
function createDOM(currFile){
var img = new Image();
img.src = currFile.result;
var li = document.createElement("li");
li.appendChild(img);
ul.appendChild(li);
li.key = currFile.name + currFile.lastModified; //给每个缩略图一个标识
li.addEventListener("click",function(){
var _li = this; //标识当前li元素
ul.removeChild(this);
fileData.forEach(function(f,i){
if(f.name+f.lastModified == _li.key)fileData.splice(i,1);
})
})
}
这里只做post的封装
function ajax(options){
var defaultOptions = {
url:"",
type:"",
data:null,
dataType:"json",
success:function(){},
error:function(){}
}
options = Object.assign({},defaultOptions,options);
if(window.XMLHttpRequest){
var xhr = new XMLHttpRequest();
}else{
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
options.success();
}else{
options.error();
}
}
}
xhr.open(options.type,options.url,true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
xhr.send(options.data);
}
以上的代码是全部的js逻辑,如果想更直观地看到效果,可将下面的html+css代码进行ctrl+v
/*css*/
<style type="text/css">
*{padding:0;margin:0;}
form{padding: 30px;width: 500px;margin: 200px auto 0;box-shadow: 0 3px 20px #ddd;}
input{display: none;}
span#addBtn{display: inline-block;padding: 25px;background: #00A09D;border-radius: 5px;color: white;position: relative;}
span#addBtn::after,span#addBtn::before{content:"";width: 25px;height: 3px;background: #fff;position: absolute;top: 0;left:0;bottom: 0;right: 0;margin: auto;}
span#addBtn::before{transform: rotate(90deg);}
div#uploadBtn{width: 150px;margin: 20px auto 0;text-align: center;color: #fff;background: #00A09D;border-radius: 5px;padding: 10px 0;}
ul.file-box{list-style: none;margin: 30px 0;}
ul.file-box::after{display: block;content: "";clear: both;}
ul.file-box li{float: left;width: 18%;margin: 10px 1% 0;border-radius: 5px;overflow: hidden;text-align: center;box-shadow: 0 3px 20px #aaa;}
ul.file-box li img{width: 90px;height:90px;vertical-align: middle;}
/*动画样式*/
.shake-btn:hover{animation: shake .5s;}
.bigger-btn:hover{animation: bigger .4s;}
@keyframes shake{
0%{transform: rotate(0deg);}
25%{transform: rotate(5deg);}
50%{transform: rotate(-10deg);}
75%{transform: rotate(5deg);}
100%{transform: rotate(0);}
}
@keyframes bigger{
0%{transform: scale(1);}
49%{transform: scale(1.1);}
51%{transform: scale(1.1);}
100%{transform: scale(1);}
}
style>
<form action="" id="fileForm" method="post">
<label>
<input type="file" name="files" multiple accept="image/jpeg,image/png,image/gif"/>
<span id="addBtn" class="bigger-btn">span>
label>
<ul class="file-box">ul>
<div id="uploadBtn" class="shake-btn">上传图片div>
form>
好像有点多啊,这是我初步的代码,封装好的完整的代码在我的github上
有兴趣的可以去看看,大家多多批评
https://github.com/mqr123/tools/blob/master/Multi/Multi-picture-uploading.js