一 . 具体效果

二 .大略实现流程和设计思路
-
大略流程
image.png
- 设计思路
将整个模块封装到jquery插件中,直接通过调用插件来实现。整个选择图片上传模块有包括三大对象,分别是:
(a)uploadTools(上传工具): 初始化界面和所有界面上的工具,并为他们绑定相应的uploadEvent事件
(b)uploadEvent(事件处理): 定义事件处理函数
(c)uploadFileList(文件处理):处理虚拟的文件列表 fileList(通过fileList就能看到上传前的所有图片信息)
三 . 主要代码
- 需要用到的参数
"uploadId":uploadId, //初始化整个功能模板的div的id
"uploadUrl":"#", //上传地址
"fileType":"*", //文件类型
"fileMaxNum":-1, //文件最大数量:-1为没有限制 ,必须为整数
"fileMaxSize":-1, //单个文件最大大小:-1为没有限制, 单位kb
"canDrag":true, //文件是否可拖拽
"isHiddenUploadBtn":false, //是否隐藏上传按钮 , 默认为不隐藏
"isHiddenCleanBtn":false, //是否隐藏清除按钮 , 默认为不隐藏
"ismultiple":true, //是否可以多文件上传
"isAutoClean":true, //是否上传后自动完成清除
"fileSavePath":"", //文件上传后后台设置的根目录
"uploadSuccess":function(){}, //上传成功后的回调函数
"uploadFalse":function(){}, //上传失败后的回调函数
2.整个的js代码
//定义一个jquery上传插件
$.fn.extend({
"initUpload":function(opt){ //传入参数opt对象
if(typeof opt !=="object"){
console.log("传入的参数有误");
return ;
}
var uploadId=$(this).attr("id")
if(uploadId==null||uploadId==""){
console.log("请传入一个有id的元素");
return ;
}
//将其余默认值赋给opt
$.each(uploadTools.getInitOption(uploadId),function(key,value){
if(opt[key]===undefined){
opt[key]=value;
}
})
uploadTools.flushOpt(opt); //保存opt
uploadTools.initWithLayout(opt); //初始化文件布局
uploadTools.initWithDrag(opt); //初始化拖拽事件
uploadTools.initWithSelectBtn(opt); //初始化选择文件按钮
uploadTools.initWithUploadBtn(opt); //初始化上传按钮
uploadTools.initWithCleanBtn(opt); //初始化清除文件按钮
uploadFileList.initFileList(opt); //初始化已添加文件列表
}
})
/****************
*上传基本工具和操作
*****************/
var uploadTools={
/*
*基本参数配置
*/
"getInitOption":function(uploadId){
var initOption={
"uploadId":uploadId, //初始化整个功能模板的div的id
"uploadUrl":"#", //上传地址
"fileType":"*", //文件类型
"fileMaxNum":-1, //文件最大数量:-1为没有限制 ,必须为整数
"fileMaxSize":-1, //单个文件最大大小:-1为没有限制, 单位kb
"canDrag":true, //文件是否可拖拽
"isHiddenUploadBtn":false, //是否隐藏上传按钮 , 默认为不隐藏
"isHiddenCleanBtn":false, //是否隐藏清除按钮 , 默认为不隐藏
"ismultiple":true, //是否可以多文件上传
"isAutoClean":true, //是否上传后自动完成清除
"fileSavePath":"", //文件上传后后台设置的根目录
"uploadSuccess":function(){}, //上传成功后的回调函数
"uploadFalse":function(){}, //上传失败后的回调函数
}
return initOption;
},
/*
*初始化布局
*/
"initWithLayout":function(opt){
console.log(opt)
var optionId=opt.uploadId;
//文件和上传,清理按钮模板
var btnsStr = '';
btnsStr += '<div class="uploadBtns">';
btnsStr += '<ul>';
btnsStr += '<li><div class="selectFileBtn">选择文件</div></li>';
if(!opt.isHiddenUploadBtn){
btnsStr += '<li><div class="uploadFileBtn"><i class="iconfont icon-shangchuan"></i></div></li>';
}
if(!opt.isHiddenCleanBtn){
btnsStr += '<li><div class="deleteFileBtn"><i class="iconfont icon-shanchu"></i></div></li>';
}
btnsStr += '</ul>';
btnsStr += '</div>';
//文件显示框
var fileStr = '';
fileStr += '<div class="box">'
fileStr += '</div>'
$("#"+optionId).append(btnsStr);
$("#"+optionId).append(fileStr)
},
/*
* 初始化拖拽事件
*/
"initWithDrag":function(opt){
if(opt.canDrag){
$(document).on({
//拖进时触发
dragenter:function(e){
e.preventDefault();
},
//拖来拖去时触发
dragover:function(e){
e.preventDefault();
},
//放置拖放元素时触发
drag:function(e){
e.preventDefault();
},
//拖出来时触发
dragleave:function(e){
e.preventDefault();
}
})
var box=$("#"+opt.uploadId+" .box");
if(box.length!==0){
$(document).on("drop",function(e){
uploadEvent.dragEvent(e,opt);
})
}
}
},
/*
*初始化选择按钮
*/
"initWithSelectBtn":function(opt){
var uploadId=opt.uploadId;
$("#"+uploadId+" .selectFileBtn").off();
$("#"+uploadId+" .selectFileBtn").on("click",function(){
uploadEvent.selectFileEvent(opt);
})
},
/*
* 初始化上传文件按钮
*/
"initWithUploadBtn":function(opt){
var uploadId=opt.uploadId;
$("#"+uploadId+" .uploadFileBtn i").css("color","#0099ff");
$("#"+uploadId+" .uploadFileBtn").off();
$("#"+uploadId+" .uploadFileBtn").on("click",function(){
uploadEvent.uploadFileEvent(opt);
})
},
/*
*初始化清除文件按钮
*/
"initWithCleanBtn":function(opt){
var uploadId=opt.uploadId;
$("#"+uploadId+" .deleteFileBtn i").css("color","#0099ff");
$("#"+uploadId+" .deleteFileBtn").off();
$("#"+uploadId+" .deleteFileBtn").on("click",function(){
uploadEvent.cleanFileEvent(opt);
})
},
/*
*time秒上传进度为100%:隐藏图片上的删除按钮->一点时间后显示图片上传成功icon
*/
"getFileUploadProgressMsg":function(opt,time){
var seconds=0;
if(time!==undefined){
seconds=time;
}
var uploadId=opt.uploadId;
$("#"+uploadId+" .status i").css("opacity","0")
var timer=setInterval(function(){
$("#"+uploadId+" .status i").addClass("icon-right");
$("#"+uploadId+" .status i").css("opacity","1")
clearInterval(timer);
//uploadTools.initWithUploadBtn(opt);
uploadTools.initWithCleanBtn(opt); //只恢复清除全部按钮 , 清除后才能初始化上传按钮
},seconds);
},
/*
* 初始化图片上的删除按钮
*/
"initWithDeleteBtn":function(opt){
uploadId=opt.uploadId;
$("#"+uploadId+" .box i").off();
$("#"+uploadId+" .box i").on("click",function(){
var thisFileItem=$(this).parent().parent()
//修改存储文件列表fileList
var index=thisFileItem.attr("fileCodeId");
var fileListArray=uploadFileList.getFileList(opt);
//fileListArray.splice(index,1); //不能使用splice,因为连续删除时fileCodeId不变,fileListArray[index]可能会不存在
delete fileListArray[index] //delete会使数组长度不变 , 但是被删除的值为undefined
uploadFileList.setFileList(fileListArray,opt);
thisFileItem.remove();
})
},
/*
*禁用文件上传
*/
"disableUploadBtn":function(opt){
if(!opt.isHiddenUploadBtn){
var uploadId=opt.uploadId;
$("#"+uploadId+" .uploadFileBtn").off();
$("#"+uploadId+" .uploadFileBtn i").css("color","#DDDDDD");
}
},
/*
*禁用清除文件按钮
*/
"disableCleanBtn":function(opt){
if(!opt.isHiddenCleanBtn){
var uploadId=opt.uploadId;
$("#"+uploadId+" .deleteFileBtn").off();
$("#"+uploadId+" .deleteFileBtn i").css("color","#DDDDDD");
}
},
/*
*禁用图片上的删除按钮
*/
"disableDeleteBtn":function(opt){
var uploadId=opt.uploadId;
$("#"+uploadId+" .box i").off();
},
/*
* 配合拖动事件的存值操作 setData
*/
"flushOpt":function(opt){
var uploadId=opt.uploadId;
$("#"+uploadId).data("opt",opt)
},
/*
* 添加文件
***判断文件是否具有被添加的条件
*/
"addFileList":function(fileList,opt){
//判断所有文件个数是否超出opt.fileMaxNum
var fileListArray=uploadFileList.getFileList(opt) //暂时的文件存储列表
var len=0; //fileListArray还存在的元素的个数(不为undefined)
for(var i=0;i<uploadFileList.getFileList(opt).length;i++){
if(uploadFileList.getFileList(opt)[i] !== undefined){
len++;
}
}
if(fileList.length+len>opt.fileMaxNum){
alert("最多只能上传"+opt.fileMaxNum+"个文件");
return;
}
for(var i=0;i<fileList.length;i++){
//判断是不是重复文件
if(uploadTools.isFileExist(fileList[i],opt)){
alert("文件''"+fileList[i].name+"''已存在啦");
continue;
}
//判断文件类型是否符合
var nameArray=fileList[i].name.split(".");
var thisType=nameArray[nameArray.length-1];
if(opt.fileType=="*"||uploadTools.isInArray(thisType,opt.fileType)){
//判断文件大小是否符合
var maxSize=opt.fileMaxSize*1000;
if(opt.fileMaxSize==-1||fileList[i].size<=maxSize){
//添加文件
var imgUrl=""; //获取文件路径
if(window.createObjectURL !== undefined){ //base
imgUrl=window.createObjectURL(fileList[i]);
}
else if(window.URL !== undefined){ //mozilla(firefox)
imgUrl=window.URL.createObjectURL(fileList[i]);
}
else if(window.webkitURL !== undefined){ /// webkit or chrome
imgUrl=window.webkitURL.createObjectURL(fileList[i]);
}
var fileId=fileListArray.length; //用来给每一个文件添加一个独一无二的标志
var imgstr="";
imgstr += '<div class="fileItem" fileCodeId="'+fileId+'">';
imgstr += '<div class="imgShow">';
imgstr += '<img src="'+imgUrl+'" width="150" height="150" />';
imgstr += '</div>';
imgstr += '<div class="status"><i class="iconfont icon-close"></i></div>';
imgstr += '<div class="fileName">'+fileList[i].name+'</div>';
imgstr += '</div>';
$("#"+opt.uploadId+" .box").eq(0).append(imgstr);
//将通过文件添加进文件列表
fileListArray[fileListArray.length]=fileList[i];
}
else{
alert("文件过大,请控制在"+opt.fileMaxSize+"kb以内");
continue; //上传到文件中只有超过最大容量的
}
}
else{
var str="不支持该文件上传,支持的文件格式有"
for(var j=0;j<opt.fileType.length;j++){
str+= " "+opt.fileType[j];
}
alert(str);
return;
}
}
uploadTools.initWithDeleteBtn(opt);
uploadFileList.setFileList(fileListArray,opt);
},
/*
*判断某个值是否在数组里
*/
"isInArray":function(str,array){
for(var i=0;i<array.length;i++){
if(array[i]==str){
return true;
}
}
return false;
},
/*
*判断文件是否已存在
*/
"isFileExist":function(file,opt){
var fileList=uploadFileList.getFileList(opt);
for(var i=0;i<fileList.length;i++){
//当图片全部删除时,会出现fileList[i]=undefined
if(fileList[i]==undefined){
continue;
}
else if(fileList[i].name==file.name && fileList[i].size==file.size){
return true;
}
}
return false;
},
}
/********
上传事件处理
********/
var uploadEvent={
/*
*拖动放置时的操作事件
**判断是否为符合配置参数的的文件
*/
"dragEvent":function(e,opt){
e.preventDefault();
var fileList=e.originalEvent.dataTransfer.files; //jquery的file要去e.originalEvent里面拿,原生JS可以直接由e.dataTransfer.files获取
uploadTools.addFileList(fileList,opt);
},
/*
* 按选择文件时触发的事件
*/
"selectFileEvent":function(opt){
var uploadId=opt.uploadId;
//添加一个type=file的按钮
var str="";
str+='<input type="file" id="fileSelectInput" class="fileSelectInput" />'
$("#"+uploadId).append(str);
if(opt.ismultiple){
$("#fileSelectInput").attr("multiple","multiple");
}
$("#fileSelectInput").on("change",function(e){
uploadTools.addFileList(this.files,opt);
$("#fileSelectInput").remove();
})
$("#fileSelectInput").click();
},
/*
*清除所有文件: 禁用选择文件按钮->清空文件列表->初始化选择文件
*/
"cleanFileEvent":function(opt){
var uploadId=opt.uploadId;
$("#fileSelectInput").remove(); //移除选择文件按钮
uploadFileList.setFileList([],opt); //清空文件列表
$("#"+uploadId+" .box").html("");
uploadTools.initWithUploadBtn(opt); //初始化上传文件:配合上传后通过清除文件来重新上传
},
/*
* 上传文件事件
*/
"uploadFileEvent":function(opt){
uploadTools.flushOpt(opt); //将opt的数据存储起来
//判断是否有上传前的回调函数
//..
var fileList=uploadFileList.getFileList(opt);
var formData=new FormData(); //记录要发送的数据
var fileNum=0; //记录被上传的文件次数,如果为0则提醒
for(var i=0;i<fileList.length;i++){
if(fileList[i]!==undefined){
formData.append("file",fileList[i]);
fileNum++;
}
}
if(fileNum==0){
alert("没有文件可以上传");
return;
}
formData.append("fileSavePath",opt.fileSavePath);
uploadTools.disableUploadBtn(opt); //禁用上传按钮
uploadTools.disableCleanBtn(opt); //禁用清除按钮
uploadTools.disableDeleteBtn(opt); //禁用图片上的删除按钮
//设置了上传文件存储地址则使用AJAX上传 , 否则模拟上传
if(opt.fileSavePath==""||opt.fileSavePath=="#"){
//模拟上传:隐藏图片上的删除按钮->一点时间后显示图片上传成功icon
uploadTools.getFileUploadProgressMsg(opt,2000);
}
else{
//使用AJAX上传
$.ajax({
type:"post",
url:opt.uploadUrl,
data:formData,
procssData:false, //data不转化为字符串
contentType:false, //避免 JQuery 对其操作,从而失去分界符,而使服务器不能正常解析文件。
success:function(data){
uploadTools.getFileUploadProgressMsg(opt);
if(opt.isAutoClean){
uploadEvent.cleanFileEvent();
}
},
error:function(e){
alert("上传文件失败");
}
})
}
},
}
/***********
*上传文件处理
***********/
var uploadFileList={
/*初始化存储已添加文件的列表*/
"initFileList":function(opt){
opt.fileList=new Array();
},
/*获取已添加文件的列表*/
"getFileList":function(opt){
return opt.fileList;
},
/*向列表添加文件*/
"setFileList":function(fileList,opt){
opt.fileList=fileList;
//nowFileList=preFileList.concat(fileList);
uploadTools.flushOpt(opt)
}
}
网友评论