美文网首页
选择图片文件(可拖动)并上传功能的实现——js对象

选择图片文件(可拖动)并上传功能的实现——js对象

作者: 方_糖 | 来源:发表于2019-01-08 20:25 被阅读0次

一 . 具体效果

效果

二 .大略实现流程和设计思路

  • 大略流程


    image.png
  • 设计思路
    将整个模块封装到jquery插件中,直接通过调用插件来实现。整个选择图片上传模块有包括三大对象,分别是:
    (a)uploadTools(上传工具): 初始化界面和所有界面上的工具,并为他们绑定相应的uploadEvent事件
    (b)uploadEvent(事件处理): 定义事件处理函数
    (c)uploadFileList(文件处理):处理虚拟的文件列表 fileList(通过fileList就能看到上传前的所有图片信息)

三 . 主要代码

    1. 需要用到的参数
      "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)
  }
}

四. 具体的流程图和完整的代码下载链接

https://download.csdn.net/download/qq_36828433/10904749

相关文章

网友评论

      本文标题:选择图片文件(可拖动)并上传功能的实现——js对象

      本文链接:https://www.haomeiwen.com/subject/cgwbrqtx.html