(二)zyUpload界面绝佳、体验超棒的HTML5上传插件

2015-04-12 12:39:02:  

一、概况

这个文件代码目前只有209行(带注释),因为他只处理文件上传相关的逻辑,比如:选择、删除之类。它相当于人体的骨骼,肉体是zyUpload,过两天我会放出全部的代码(JAVA版)。

二、参数配置

下面展示zyFile的属性及其对应的内容含义等,(灰色的参数不需要用户初始化)。

属性或方法名参数值或默认方法释义
fileInputnull

选择文件按钮dom对象

uploadInput
null

上传文件按钮dom对象

dragDrop
null

拖拽敏感区域dom对象

url
""
上传action绝对路径
uploadFile[]

需要上传的文件数组

lastUploadFile[]

上一次选择的文件数组,方便继续上传使用

perUploadFile[]

存放永久的文件数组,方便删除使用

fileNum
0

代表文件总个数,因为涉及到继续添加,所以下一次添加需要在它的基础上添加索

filterFile

function(files) {

  return files;

}

提供给外部的过滤文件格式等的接口,外部需要把过滤后的文件返回

onSelect

function(selectFile, files){}

提供给外部获取选中的文件,供外部实现预览等功能  selectFile:当前选中的文件  allFiles:还没上传的全部文件

onDelete

function(file, files){}

提供给外部获取删除的单个文件,供外部实现删除效果  file:当前删除的文件  files:删除之后的文件

onProgress

function(file, loaded, total){}

提供给外部获取单个文件的上传进度,供外部实现上传进度效果


onSuccess

function(file, responseInfo){}

提供给外部获取单个文件上传成功,供外部实现成功效果

onFailure

function(file, responseInfo){}

提供给外部获取单个文件上传失败,供外部实现失败效果

onComplete

function(responseInfo){}

提供给外部获取全部文件上传完成,供外部实现完成效果

onDragOver

function() {}

提供给外部获取拖动移动在目标上的方法

onDragLeave

function() {}

提供给外部获取拖动离开的方法

三、初始化示例

// 初始化插件
    $("#demo").zyUpload({
        width            :   "650px",                 // 宽度
        height           :   "400px",                 // 宽度
        itemWidth        :   "120px",                 // 文件项的宽度
        itemHeight       :   "100px",                 // 文件项的高度
        url              :   "/upload/UploadAction",  // 上传文件的路径
        multiple         :   true,                    // 是否可以多个文件上传
        dragDrop         :   true,                    // 是否可以拖动上传文件
        del              :   true,                    // 是否可以删除文件
        finishDel        :   false,                    // 是否在上传文件完成后删除预览
        /* 外部获得的回调接口 */
        onSelect: function(selectFiles, allFiles){    // 选择文件的回调方法  selectFile:当前选中的文件  allFiles:还没上传的全部文件
            console.info("当前选择了以下文件:");
            console.info(selectFiles);
        },
        onDelete: function(file, files){              // 删除一个文件的回调方法 file:当前删除的文件  files:删除之后的文件
            console.info("当前删除了此文件:");
            console.info(file.name);
        },
        onSuccess: function(file, response){          // 文件上传成功的回调方法
            console.info("此文件上传成功:");
            console.info(file.name);
        },
        onFailure: function(file, response){          // 文件上传失败的回调方法
            console.info("此文件上传失败:");
            console.info(file.name);
        },
        onComplete: function(response){                 // 上传完成的回调方法
            console.info("文件上传完成");
            console.info(response);
        }
    });

zyFile.js的全部代码:

/*
 * zyFile.js 基于HTML5 文件上传的核心脚本 http://www.52doit.com
 * by zhangyan 2014-06-21   QQ : 623585268
*/

var ZYFILE = {
        fileInput : null,             // 选择文件按钮dom对象
        uploadInput : null,           // 上传文件按钮dom对象
        dragDrop: null,                  // 拖拽敏感区域
        url : "",                        // 上传action路径
        uploadFile : [],                // 需要上传的文件数组
        lastUploadFile : [],          // 上一次选择的文件数组,方便继续上传使用
        perUploadFile : [],           // 存放永久的文件数组,方便删除使用
        fileNum : 0,                  // 代表文件总个数,因为涉及到继续添加,所以下一次添加需要在它的基础上添加索引
        /* 提供给外部的接口 */
        filterFile : function(files){ // 提供给外部的过滤文件格式等的接口,外部需要把过滤后的文件返回
            return files;
        },
        onSelect : function(selectFile, files){      // 提供给外部获取选中的文件,供外部实现预览等功能  selectFile:当前选中的文件  allFiles:还没上传的全部文件
            
        },
        onDelete : function(file, files){            // 提供给外部获取删除的单个文件,供外部实现删除效果  file:当前删除的文件  files:删除之后的文件
            
        },
        onProgress : function(file, loaded, total){  // 提供给外部获取单个文件的上传进度,供外部实现上传进度效果
            
        },
        onSuccess : function(file, responseInfo){    // 提供给外部获取单个文件上传成功,供外部实现成功效果
            
        },
        onFailure : function(file, responseInfo){    // 提供给外部获取单个文件上传失败,供外部实现失败效果
        
        },
        onComplete : function(responseInfo){         // 提供给外部获取全部文件上传完成,供外部实现完成效果
            
        },
        
        /* 内部实现功能方法 */
        // 获得选中的文件
        //文件拖放
        funDragHover: function(e) {
            e.stopPropagation();
            e.preventDefault();
            this[e.type === "dragover"? "onDragOver": "onDragLeave"].call(e.target);
            return this;
        },
        // 获取文件
        funGetFiles : function(e){  
            var self = this;
            // 取消鼠标经过样式
            this.funDragHover(e);
            // 从事件中获取选中的所有文件
            var files = e.target.files || e.dataTransfer.files;
            self.lastUploadFile = this.uploadFile;
            this.uploadFile = this.uploadFile.concat(this.filterFile(files));
            var tmpFiles = [];
            
            // 因为jquery的inArray方法无法对object数组进行判断是否存在于,所以只能提取名称进行判断
            var lArr = [];  // 之前文件的名称数组
            var uArr = [];  // 现在文件的名称数组
            $.each(self.lastUploadFile, function(k, v){
                lArr.push(v.name);
            });
            $.each(self.uploadFile, function(k, v){
                uArr.push(v.name);
            });
            
            $.each(uArr, function(k, v){
                // 获得当前选择的每一个文件   判断当前这一个文件是否存在于之前的文件当中
                if($.inArray(v, lArr) < 0){  // 不存在
                    tmpFiles.push(self.uploadFile[k]);
                }
            });
            
            // 如果tmpFiles进行过过滤上一次选择的文件的操作,需要把过滤后的文件赋值
            //if(tmpFiles.length!=0){
                this.uploadFile = tmpFiles;
            //}
            
            // 调用对文件处理的方法
            this.funDealtFiles();
            
            return true;
        },
        // 处理过滤后的文件,给每个文件设置下标
        funDealtFiles : function(){
            var self = this;
            // 目前是遍历所有的文件,给每个文件增加唯一索引值
            $.each(this.uploadFile, function(k, v){
                // 因为涉及到继续添加,所以下一次添加需要在总个数的基础上添加
                v.index = self.fileNum;
                // 添加一个之后自增
                self.fileNum++;
            });
            // 先把当前选中的文件保存备份
            var selectFile = this.uploadFile;  
            // 要把全部的文件都保存下来,因为删除所使用的下标是全局的变量
            this.perUploadFile = this.perUploadFile.concat(this.uploadFile);
            // 合并下上传的文件
            this.uploadFile = this.lastUploadFile.concat(this.uploadFile);
            
            // 执行选择回调
            this.onSelect(selectFile, this.uploadFile);
            console.info("继续选择");
            console.info(this.uploadFile);
            return this;
        },
        // 处理需要删除的文件  isCb代表是否回调onDelete方法  
        // 因为上传完成并不希望在页面上删除div,但是单独点击删除的时候需要删除div   所以用isCb做判断
        funDeleteFile : function(delFileIndex, isCb){
            var self = this;  // 在each中this指向没个v  所以先将this保留
            
            var tmpFile = [];  // 用来替换的文件数组
            // 合并下上传的文件
            var delFile = this.perUploadFile[delFileIndex];
            //console.info(delFile);
            // 目前是遍历所有的文件,对比每个文件  删除
            $.each(this.uploadFile, function(k, v){
                if(delFile != v){
                    // 如果不是删除的那个文件 就放到临时数组中
                    tmpFile.push(v);
                }
            });
            this.uploadFile = tmpFile;
            if(isCb){  // 执行回调
                // 回调删除方法,供外部进行删除效果的实现
                self.onDelete(delFile, this.uploadFile);
            }
            
            console.info("还剩这些文件没有上传:");
            console.info(this.uploadFile);
            return true;
        },
        // 上传多个文件
        funUploadFiles : function(){
            var self = this;  // 在each中this指向没个v  所以先将this保留
            // 遍历所有文件  ,在调用单个文件上传的方法
            $.each(this.uploadFile, function(k, v){
                self.funUploadFile(v);
            });
        },
        // 上传单个个文件
        funUploadFile : function(file){
            var self = this;  // 在each中this指向没个v  所以先将this保留
            var formdata = new FormData();
            formdata.append("file", file);     
            // 添加裁剪的坐标和宽高发送给后台
            if($("#uploadTailor_"+file.index).length>0){
                // 除了这样获取不到zyUpload的值啊啊啊啊啊啊啊啊啊啊啊
                formdata.append("tailor", $("#uploadTailor_"+file.index).attr("tailor"));    
            }
            var xhr = new XMLHttpRequest();
            // 绑定上传事件
            // 进度
            xhr.upload.addEventListener("progress",     function(e){
                // 回调到外部
                self.onProgress(file, e.loaded, e.total);
            }, false); 
            // 完成
            xhr.addEventListener("load", function(e){
                // 从文件中删除上传成功的文件  false是不执行onDelete回调方法
                self.funDeleteFile(file.index, false);
                // 回调到外部
                self.onSuccess(file, xhr.responseText);
                if(self.uploadFile.length==0){
                    // 回调全部完成方法
                    self.onComplete("全部完成");
                }
            }, false);  
            // 错误
            xhr.addEventListener("error", function(e){
                // 回调到外部
                self.onFailure(file, xhr.responseText);
            }, false);  
            
            xhr.open("POST",self.url, true);
            xhr.send(formdata);
        },
        // 返回需要上传的文件
        funReturnNeedFiles : function(){
            return this.uploadFile;
        },
        
        // 初始化
        init : function(){  // 初始化方法,在此给选择、上传按钮绑定事件
            var self = this;  // 克隆一个自身
            
            if (this.dragDrop) {
                this.dragDrop.addEventListener("dragover", function(e) { self.funDragHover(e); }, false);
                this.dragDrop.addEventListener("dragleave", function(e) { self.funDragHover(e); }, false);
                this.dragDrop.addEventListener("drop", function(e) { self.funGetFiles(e); }, false);
            }
            
            // 如果选择按钮存在
            if(self.fileInput){
                // 绑定change事件
                this.fileInput.addEventListener("change", function(e) {
                    self.funGetFiles(e); 
                }, false);    
            }
            
            // 如果上传按钮存在
            if(self.uploadInput){
                // 绑定click事件
                this.uploadInput.addEventListener("click", function(e) {
                    self.funUploadFiles(e); 
                }, false);    
            }
        }
};

上面是吧整个上传插件的骨骼部分讲完了,接下来的文章会继续把肉体的部分的使用高速大家,源码也会提供下载,有什么不明白的请加我QQ留言(623585268),谢谢。


zyUpload JavaScript版实例代码:

http://yun.baidu.com/share/link?shareid=3705093182&uk=2972370755


zyUpload JAVA版实例代码:

http://yun.baidu.com/share/link?shareid=3707308326&uk=2972370755


zyUpload PHP版实例代码:

http://yun.baidu.com/share/link?shareid=3709895291&uk=2972370755



精品书籍

更多

HTML5与CSS3权威指南代码清单
Sass和Compass设计师指南
JavaScript框架高级编程