官网: http://fex.baidu.com/webuploader/doc/index.html
文件目录
css文件下有一个字体样式文件,两个上传样式, 上传控件样式可以自己编写样式 覆盖, 根据页面进行修改;
MyUpload.js 上传控件js,能扩展;
webuploader/Uploader.swf flash需要使用的文件;
两次上传:选择文件(直接上传,),服务端返回图片路径,存储路径。提交表单,存储路径提交给服务端;
上传流程:用户选取文件之后,文件被加入上传队列,创建缩略图,发送一次ajax (一个文件发送一次),向服务端索要token,开始上传,完成上传,页面显示上传状态(成功,失败), 文件对象添加服务端返回的数据,用户点击表单提交,触发回调方法,把文件对象的数据(文件存储路径,文件名,,需要提交的值,可选)赋值给隐藏域的input, 跟随表单一起提交
回显:通过init传进图片的url,创建DOM结构,绑定删除事件
MyUpload源码(带回显功能):
MyUpload.js
(function (window) { function MyUpload(options) { // flash路径 this.swf = './../webuploader/Uploader.swf'; // 提交文件的所有数据 this.datas = []; // 计算回显后还能上传多少个文件 this.uploadCount = this.verifyNum(options.fileNumLimit); // 允许上传数量 this.fileNumLimit = this.verifyNum(options.fileNumLimit); // 上传数量计数 this.count = 0; // 优化retina, 在retina下这个值是2 this.ratio = window.devicePixelRatio || 1; // 缩略图大小 this.thumbnailWidth = 100 * this.ratio; this.thumbnailHeight = 100 * this.ratio; // layer弹层变量 this.lay = window.layer || ""; // 上传成功触发 this.uploadSuccess = options.uploadSuccess; // 上传出错触发 this.uploadError = options.uploadError; // 上传完触发, 不管成功或失败 this.uploadComplete = options.uploadComplete; // 上传删除 this.uploadDelete = options.uploadDelete; // 创建实例传的参数 this.options = options; // 判断是否有必填参数 this.expectParam(); } // 回显函数 MyUpload.prototype.init = function(params) { var _this = this, data = params; // 判断传递进来的参数是否是数组 if(Object.prototype.toString.call(data) === '[object Array]') { // 遍历参数 并创建DOM结构 $.each(data, function(i, n) { var $li = $( '<div class="file-item thumbnail eached"><a><img class="echoed"></a><div class="remove-this"><i class="icon iconfont icon-del-copy"></i></div><div class="load"></div></div>' ), $img = $li.find('img'), $a = $li.find('a'), $load = $li.find('div.load'); $load.text('历史图片加载中') // 根据isSafe拼接url if (_this.options.formData.isSafe) { var accessKey; if (typeof _this.options.accessKey === 'string') { accessKey = _this.options.accessKey; } else { _this.errHint('accessKey错误'); } $a.attr('href', n + '?' + accessKey); $img.attr('src', n + '?' + accessKey); } else { $img.attr('src', n); $a.attr('href', n); } $(_this.options.container + ' .gallery').append($li); // 监听图片加载完成 $img.each(function (i, e) { var imgsrc = $(e).attr("src"); $(e).load(function () { $load.text('图片加载完成'); setTimeout(function() { $load.text('历史图片'); }, 600); }) // .error(function () { // 图片加载失败 提示信息, // $("<p> error " + imgsrc + "</p>").appendTo($li); // $(e).attr("src", "./images/no-preview.png"); // }); }); _this.datas.push({url: n}); }); // 回显后能上传的个数 = 允许上传的数量-回显的数量 _this.uploadCount = _this.fileNumLimit - data.length; // 绑定删除事件 $(_this.options.container + ' .eached .remove-this').click(function () { var deleteUrl = $($(this).parent().find('a img')).attr('src'), dataIndex; $.each(_this.datas, function(i, n) { if(_this.datas[i].url === deleteUrl) { dataIndex = i; data.splice(i,1); } }); // 删除回显图片,通知使用者 if (typeof _this.uploadDelete === 'function') { _this.uploadDelete(deleteUrl); } // 从datas中删除该条数据 _this.datas.splice(dataIndex, 1); // 删除DOM该条数据的结构 $(this).parent().remove(); _this.removerFileMessage(_this.options, _this.shape.options); _this.uploadCount = _this.fileNumLimit - data.length; }); } else { _this.errHint('init参数错误'); return false; } } // 判断传递进来的参数是对象, 参数是否有值初始参数之前 MyUpload.prototype.expectParam = function () { // 参数必须为对象 if (Object.prototype.toString.call(this.options) !== '[object Object]') { this.errHint('createUpload()参数必须是对象') return false; } // // 预览图片 允许空值,boolean // if (typeof this.options.preview === 'undefined' || this.options.preview) { // this.options.preview = true; // $('head').append('<link rel="stylesheet" href="./jquery-magnific-popup/magnific-popup.css">'); // $('body').append('<script type="text/javascript" src="./jquery-magnific-popup/jquery.magnific-popup.min.js"></script>'); // } // 根据页面加载按钮样式 if (this.options.buttonStyle === 2 || this.options.buttonStyle === 3) { $('head').append('<link rel="stylesheet" href="./css/button.css">'); } else if (this.options.buttonStyle === 1 || typeof this.options.buttonStyle === 'undefined') { $('head').append('<link rel="stylesheet" href="./css/imgButton.css">'); } if (!(this.options.tokenPath) || typeof this.options.tokenPath !== 'string') { this.errHint('tokenPath为空或不是为string'); return false; } if (!(this.options.server) || typeof this.options.server !== 'string') { this.errHint('server为空或不是为string'); return false; } if (!(this.options.container) || typeof this.options.container !== 'string') { this.errHint('container为空或不是为string类型'); return false; } if (typeof $(this.options.container)[0] === 'undefined') { this.errHint('上传容器不存在' + this.options.container); return false; } // 字体图标 $('head').append('<link rel="stylesheet" href="//at.alicdn.com/t/font_714144_66kol75icda.css">'); $('head').append('<link rel="stylesheet" href="./css/font.css">'); // 预览图片 $('head').append('<link rel="stylesheet" href="./jquery-magnific-popup/magnific-popup.css">'); $('body').append('<script type="text/javascript" src="./jquery-magnific-popup/jquery.magnific-popup.min.js"></script>'); // 创建上传的DOM结构 this.establishInitDOM(this.options); // 初始WebUploader this.createUpload(this.options); } // 创建上传按钮 容器的DOM结构, 初始参数之前 MyUpload.prototype.establishInitDOM = function (options) { var styleDOM, $div, container = options.container; if (!(typeof container === 'string')) { this.errHint('containerId不是string类型'); return false; } if (typeof options.buttonStyle === 'number' || typeof options.buttonStyle === 'undefined') { if (options.buttonStyle === 1 || typeof options.buttonStyle === 'undefined') { styleDOM = '<i class="iconfont icon-add1"></i>'; $div = $('<div id="fileList' + options.container.slice(1) + '" class="fileList-1 uploader-list-1 clear gallery"></div><div id="filePicker' + options.container.slice(1) +'" class="filePicker-1" ">' + styleDOM + '</div>'); $(container).append($div).addClass('uploader-container'); } else if(options.buttonStyle === 2){ styleDOM = '选择上传图片'; $div = $('<div id="fileList' + options.container.slice(1) + '" class="fileList uploader-list clear gallery"></div><div class="filePicker" id="filePicker' + options.container.slice(1) +'">' + styleDOM + '</div>'); $(container).append($div); } else if (options.buttonStyle === 3) { styleDOM = '选择上传图片'; $div = $('<div class="filePicker" id="filePicker' + options.container.slice(1) +'">' + styleDOM + '</div><div id="fileList' + options.container.slice(1) +'" class="fileList uploader-list clear gallery"></div>'); $(container).append($div); } } else { this.errHint('buttonStyle不是number类型') return false; } } // 超出上传数量限制隐藏上传按钮 MyUpload.prototype.removerFileMessage = function (options, shapeOptions) { var uploaderNum = $(options.container).find('.file-item.thumbnail').length; if (options.buttonStyle === 1 || typeof options.buttonStyle === 'undefined') { if (uploaderNum >= options.fileNumLimit) { $(shapeOptions.pick).hide(); } if (uploaderNum < options.fileNumLimit) { $(shapeOptions.pick).show(); } } } // 上传错误信息提示 MyUpload.prototype.errorType = function (type, options) { var fileNumLimit = options.fileNumLimit, accept = options.accept[0].extensions, uploaderNum = $('.file-item.thumbnail').length; if (type == "Q_TYPE_DENIED") { this.errHint("请上传" + accept + "格式文件"); } else if (type == "Q_EXCEED_SIZE_LIMIT") { this.errHint("文件总大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 * options.fileNumLimit + 'MB'); } else if (type == 'Q_EXCEED_NUM_LIMIT') { this.errHint("文件超出" + uploaderNum + "个, 自动选取位置靠前的文件") } else if (type == 'F_EXCEED_SIZE') { this.errHint("文件大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 + 'MB'); } else if (type == 'F_DUPLICATE') { this.errHint("重复的图片、请重新上传"); } else { this.errHint("上传出错,请重新上传"); } } // 参数错误提示信息 MyUpload.prototype.errHint = function(message) { if (this.lay) { this.lay.msg(message); } else { alert(message); } } // 验证上传类型 MyUpload.prototype.verifyType = function (accept) { if (accept === 'images') { return { title: 'Images', extensions: 'jpg,jpeg,png,bmp', // mimeTypes: 'image/jpg,image/jpeg,image/png,image/bmp' } } else if (accept === 'file') { return { title: '上传文件', extensions: 'jpg,jpeg,bmp,png,pdf,xls,xlsx,docx,zip', // mimeTypes: 'image/jpg,image/bmp,image/jpeg,image/png,application/x-zip-compressed,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' } } else if(typeof accept === 'object') { if (accept.type === 'custom' && typeof accept.extensions === 'string') { return { title: '自定义', extensions: accept.extensions, // mimeTypes: 'image/jpg,image/jpeg,image/png,image/bmp' } } else { this.errHint('accept参数有误'); return false; } } else { return { title: 'Images', extensions: 'jpg,jpeg,png,bmp', // mimeTypes: 'image/jpg,image/jpeg,image/png,image/bmp' } } } // 验证formData,compress为对象, 并返回值 MyUpload.prototype.verifyFormData_compress = function (params) { if (Object.prototype.toString.call(params) === '[object Object]') { return params; } else { return ''; } } // 验证上传个数为number类型, 并返回值 MyUpload.prototype.verifyNum = function (fileNumLimit) { if (typeof fileNumLimit === 'number') { return fileNumLimit; } else { return 10; } } // 根据参数添加fileListid MyUpload.prototype.verifyDnd = function (params) { if (typeof params.buttonStyle === 'number' && params.buttonStyle === 1 || typeof params.buttonStyle === 'undefined') { return params.container; } else { return '#fileList' + params.container.slice(1); } } // 验证duplicate为对象, 并返回值 MyUpload.prototype.verifyDuplicate = function (params) { if (Object.prototype.toString.call(params) === '[object Boolean]') { return params; } else { return true; } } // 初始上传参数 MyUpload.prototype.initParams = function (params) { var settings = { // 自动上传 auto: true, // 拖拽容器 dnd: this.verifyDnd(params), // 粘贴容器 paste: params.container, // 强制使用flash上传 // runtimeOrder: 'flash', // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick: '#filePicker' + params.container.slice(1), // 禁掉页面打开图片的功能 disableGlobalDnd: true, // swf文件路径 swf: this.swf, // 文件接收服务端 server: params.server, // 只允许选择图片文件。 accept: this.verifyType(params.accept), // method: 'GET', formData: this.verifyFormData_compress(params.formData), // 上传个数 没依赖WebUploader来限制上传数量 fileNumLimit: 99, //上传文件单个大小单位(B) fileSingleSizeLimit: params.fileSingleSizeLimit || 1 * 1024 * 1024 * 2, // 上传文件总大小单位(B) // fileSizeLimit: params.fileSingleSizeLimit || 1 * 1024 * 1024 * 2 // 扩展的参数 // 允许重复的文件上传 duplicate: this.verifyDuplicate(params.duplicate), // 压缩图片 compress: this.verifyFormData_compress(params.compress), // 是否允许在文件传输时提前把下一个文件准备好 prepareNextFile: params.prepareNextFile || '', } return settings; } // 创建上传功能,uploader方法都包含在内 MyUpload.prototype.createUpload = function (options) { var _this = this; _this.shape = options.container.slice(1); if (!WebUploader.Uploader.support()) { alert('Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器'); throw new Error('WebUploader does not support the browser you are using.'); } // 调用jquery插件,查看原图 $('.gallery').magnificPopup({ delegate: 'a', type: 'image', gallery: { enabled: true } }); _this.shape = new WebUploader.Uploader(_this.initParams(options)); // 当文件被加入队列之前触发 // uploader.on('beforeFileQueued', function (file) { // }); // 当一批文件添加进队列以后触发 // uploader.on('filesQueued', function (file) { // }) // 当文件被加入队列是触发 _this.shape.on('fileQueued', function (file) { // 加入队列前 判断可以上传的数量 if (_this.uploadCount <= _this.count) { _this.errorType('Q_EXCEED_NUM_LIMIT', _this.shape.options); return false; } _this.count++; var $li = $( '<div id="' + file.id + '" class="file-item thumbnail"><a><img></a><div class="remove-this"></div></div>' ), $img = $li.find('img'); // $list为容器jQuery实例 $('#fileList' + options.container.slice(1)).append($li); // 创建缩略图 // 如果为非图片文件,可以不用调用此方法。 // thumbnailWidth x thumbnailHeight 为 100 x 100 _this.shape.makeThumb(file, function (error, src) { if (error) { $li.find('a').attr('href', './images/no-preview.png'); $img.replaceWith('<span class="preview">上传的文件不支持预览,但不影响上传。</span><img src="./images/no-preview.png" alt="不能预览">'); return; } $img.attr('src', src); }, _this.thumbnailWidth, _this.thumbnailHeight); _this.removerFileMessage(options, _this.shape.options); // 绑定删除事件 $('#fileList' + options.container.slice(1)).on('click', '.remove-this', function () { if ($(this).parent().attr('id') == file.id) { var result; // 遍历datas, $.each(_this.datas, function (i, n) { if (!!n.WUfile && n.WUfile.id === file.id) { result = i; // 通知使用者删除了哪项 _this.uploadDelete(n); } }); // 从上传队列中删除, _this.shape.removeFile(file, true); // 删除datas该项的数据 _this.datas.splice(result,1); // 删除DOM结构 $(this).parent().remove(); // 是否显示删除按钮 _this.removerFileMessage(options, _this.shape.options); // 计数器-1 _this.count = _this.count - 1; } }); // $.support.cors = true; // 当文件加入队列就去请求一次token,一个文件发送一次 $.ajax({ type: 'GET', async: false, url: options.tokenPath, dataType: 'json', success: function (response) { file.token = response.token; } }); }); // 文件开始上传前 触发 // uploader.on('uploadStart', function (file) { // }); // 文件上传过程中创建进度条实时显示。 _this.shape.on('uploadProgress', function (file, percentage) { var $lis = $('#' + file.id), $percent = $lis.find('.progress span'); // 避免重复创建 if (!$percent.length) { $percent = $('<p class="progress"><span></span></p>').appendTo($lis).find('span'); } $percent.css('width', percentage * 100 + '%'); }); // 当某个文件的分块在发送前触发 block文件对象,data上传附带的参数 _this.shape.on('uploadBeforeSend', function (block, data) { // file的token赋值给data data.token = block.file.token; // 上传的安全图参数赋值给file block.file.isSafe = data.isSafe || '' }) // 文件上传成功,给item添加成功class, 用样式标记上传成功。 _this.shape.on('uploadSuccess', function (file, response) { // $('#' + file.id).addClass('upload-state-done'); var $li = $('#' + file.id), $success = $li.find('div.success'), $a = $li.find('a'); // 避免重复创建 if (!$success.length) { $success = $('<div class="success"></div>').appendTo($li); // 预览原图 // if (options.preview) {// } var accessKey; // 图片为安全图 if (file.isSafe) { // url拼接accessKey if(typeof options.accessKey === 'string') { accessKey = options.accessKey; } else { _this.errHint('accessKey错误'); } $a.attr('href', response.url + '?' + accessKey); } else { $a.attr('href', response.url); } } if (response.statusText == '上传成功') { $success.text('上传成功'); response.WUfile = file; _this.datas.push(response) } else { $success.text('上传失败').css({ 'color': 'red',}); $a.find('span').html('上传失败,请检查文件格式,再上传').css({ 'color': 'red', 'font-size': '12px' }); } // 上传成功触发 if (typeof _this.uploadSuccess === 'function') { _this.uploadSuccess(file, response); } }); // 文件上传失败,显示上传出错。 _this.shape.on('uploadError', function (file, error) { var $li = $('#' + file.id), $error = $li.find('p.error'); // 避免重复创建 if (!$error.length) { $error = $('<div class="error"></div>').appendTo($li); } $error.text('上传失败'); // 上传失败触发 if(typeof _this.uploadError === 'function') { _this.uploadError(file, error); } }); // 完成上传完了,成功或者失败,先删除进度条。 _this.shape.on('uploadComplete', function (file) { $('#' + file.id).find('.progress').remove(); $('#' + file.id).find('.remove-this').append('<i class="icon iconfont icon-del-copy"></i>'); // 上传完触发 if(typeof _this.uploadComplete === 'function') { _this.uploadComplete(file); } }); // 监听错误信息 _this.shape.on("error", function (type) { _this.errorType(type, _this.shape.options); }); // 刷新WebUploader _this.shape.refresh(); } window.MyUpload = MyUpload; })(window);
MyUpload源码:
MyUpload.js
(function (jQuery, window) { function MyUpload(options) { // flash路径 this.swf = './../webuploader/Uploader.swf' // 提交文件的所有数据 this.successGather = [], // 提交文件的存储路径 this.successData = [], // 优化retina, 在retina下这个值是2 this.ratio = window.devicePixelRatio || 1, // 缩略图大小 this.thumbnailWidth = 100 * this.ratio, this.thumbnailHeight = 100 * this.ratio, // layer弹层变量 this.lay = window.layer || ""; this.options = options; this.createUpload(this.options); } // 回调方法, MyUpload.prototype.backFun = function (back) { var _this = this; if (!(typeof back === 'function')) { alert('不是一个函数'); return false; } $.each(_this.successGather, function (i, n) { if (n.path !== '') { _this.successData.push(n.params.path); _this.successData.push(n.uploadIndex) } }); back(this.successData, this.successGather); } // 判断传递进来的参数是对象, 参数是否有值初始参数之前 MyUpload.prototype.expectParam = function (params) { // 参数必须为对象 if (Object.prototype.toString.call(params) !== '[object Object]') { alert('createUpload()参数必须是对象') return false; } // 预览图片 允许空值,boolean if (typeof params.preview === 'undefined' || params.preview) { params.preview = true; $('head').append('<link rel="stylesheet" href="./../magnific-popup.css">'); $('body').append('<script type="text/javascript" src="./../jquery.magnific-popup.min.js"></script>'); } // 根据页面加载按钮样式 if (params.buttonStyle === 1) { $('head').append('<link rel="stylesheet" href="./css/imgButton.css">'); } else { $('head').append('<link rel="stylesheet" href="./css/button.css">'); } if (!(params.tokenPath) || typeof params.tokenPath !== 'string') { alert('tokenPath为空或不是为string'); return false; } if (!(params.server) || typeof params.server !== 'string') { alert('server为空或不是为string'); return false; } if (!(params.dnd) || typeof params.dnd !== 'string') { alert('dnd为空或不是为string'); return false; } } // 创建上传按钮 容器的DOM结构, 初始参数之前 MyUpload.prototype.establishInitDOM = function (options, index) { var styleDOM, $div; if (!(typeof options.dnd === 'string')) { alert('containerId不是string类型'); return false; } if (typeof options.buttonStyle === 'number') { if (options.buttonStyle === 1) { styleDOM = '<i class="iconfont icon-add1"></i>'; $div = $('<div id="fileList' + index + '"class="fileList uploader-list clear gallery"></div><div class="filePicker" id="filePicker' + index + '">' + styleDOM + '</div>'); $(options.dnd).eq(index).append($div); $(options.dnd).eq(index).addClass(options.dnd.split('.')[1] + index); } else if(options.buttonStyle === 2){ styleDOM = '选择上传图片'; $div = $('<div id="fileList' + index + '"class="fileList uploader-list clear gallery"></div><div class="filePicker" id="filePicker' + index + '">' + styleDOM + '</div>'); $(options.dnd).eq(index).append($div); $(options.dnd).eq(index).addClass(options.dnd.split('.')[1] + index); } else if (options.buttonStyle === 3) { styleDOM = '选择上传图片'; $div = $('<div class="filePicker" id="filePicker' + index + '">' + styleDOM + '</div><div id="fileList' + index + '"class="fileList uploader-list clear gallery"></div>'); $(options.dnd).eq(index).append($div); $(options.dnd).eq(index).addClass(options.dnd.split('.')[1] + index); } } else { alert('buttonStyle不是number类型') return false; } } // 超出上传数量限制隐藏上传按钮 MyUpload.prototype.removerFileMessage = function (options) { var uploaderNum = $(options.dnd).find('.file-item.thumbnail').length; if (uploaderNum >= options.fileNumLimit) { $(options.pick).hide(); } if (uploaderNum < options.fileNumLimit) { $(options.pick).show(); } } // 错误信息提示 MyUpload.prototype.errorType = function (type, options, index) { var fileNumLimit = options.fileNumLimit[index] || options.fileNumLimit, accept = options.accept[0].extensions; if (this.lay) { if (type == "Q_TYPE_DENIED") { lay.msg("请上传" + accept + "格式文件"); } else if (type == "Q_EXCEED_SIZE_LIMIT") { lay.msg("文件总大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 * options.fileNumLimit + 'MB'); } else if (type == 'Q_EXCEED_NUM_LIMIT') { lay.msg("文件超出" + fileNumLimit + "个, 自动选取位置靠前的文件") } else if (type == 'F_EXCEED_SIZE') { lay.msg("文件大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 + 'MB'); } else if (type == 'F_DUPLICATE') { alert("重复的图片、请重新上传"); } else { lay.msg("上传出错,请重新上传"); } } else { if (type == "Q_TYPE_DENIED") { alert("请上传" + accept + "格式文件"); } else if (type == "Q_EXCEED_SIZE_LIMIT") { alert("文件总大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 * options.fileNumLimit + 'MB'); } else if (type == 'Q_EXCEED_NUM_LIMIT') { alert("文件超出" + fileNumLimit + "个, 自动选取位置靠前的文件") } else if (type == 'F_EXCEED_SIZE') { alert("文件大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 + 'MB'); } else if (type == 'F_DUPLICATE') { alert("重复的图片、请重新上传"); } else { alert("上传出错,请重新上传"); } } } // 验证上传类型 MyUpload.prototype.verifyType = function (accept) { if (accept === 'images') { return { title: 'Images', extensions: 'jpg,jpeg,png,bmp', mimeTypes: 'image/jpg,image/jpeg,image/png,image/bmp' } } else if (accept === 'file') { return { title: '上传文件', extensions: 'jpg,jpeg,bmp,png,pdf,xls,xlsx,docx,zip', mimeTypes: 'image/jpg,image/bmp,image/jpeg,image/png,application/x-zip-compressed,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' } } else { return { title: 'Images', extensions: 'jpg,jpeg,png,bmp', mimeTypes: 'image/jpg,image/jpeg,image/png,image/bmp' } } } // 验证上传安全图为boolean类型还是Array 并返回值 MyUpload.prototype.verifySafe = function (params, index) { if (typeof params.isSafe === 'boolean') { return params.isSafe; } else if (Object.prototype.toString.call(params.isSafe) === '[object Array]') { if (params.isSafe[index] == false || params.isSafe[index]) { if (params.isSafe[index]) { if (!(params.access)) { alert('access为空'); } } return params.isSafe[index]; } else { return params.isSafe[0]; } } else { return false; } } // 验证上传个数为number类型还是Array 并返回值 MyUpload.prototype.verifyNum = function (params, index) { if (typeof params.fileNumLimit === 'number') { return params.fileNumLimit; } else if (Object.prototype.toString.call(params.fileNumLimit) === '[object Array]') { if (params.fileNumLimit[index]) { return params.fileNumLimit[index]; } else { return params.fileNumLimit[0] } } else { return 10; } } MyUpload.prototype.verifyDnd = function (params, index) { if (typeof params.buttonStyle === 'number' && params.buttonStyle === 1) { return params.dnd + index; } else { return '#fileList' + index; } } // 初始上传参数 MyUpload.prototype.initParams = function (params, index) { var settings = { // 自动上传 auto: true, // 拖拽容器 dnd: this.verifyDnd(params, index), // 粘贴容器 paste: params.dnd + index, // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick: '#filePicker' + index, // 禁掉页面打开图片的功能 disableGlobalDnd: true, // swf文件路径 swf: this.swf, // 文件接收服务端。 server: params.server, // 只允许选择图片文件。 accept: this.verifyType(params.accept), // method: 'GET', formData: { // 安全图片参数 isSafe: this.verifySafe(params, index) }, // 不允许重复的文件上传 duplicate: false, // 上传个数 fileNumLimit: this.verifyNum(params, index), //上传文件单个大小单位(B) fileSingleSizeLimit: params.fileSingleSizeLimit || 1 * 1024 * 1024 * 2, // 上传文件总大小单位(B) // fileSizeLimit: params.fileSingleSizeLimit || 1 * 1024 * 1024 * 2 } return settings; } // 创建上传功能,uploader方法都包含在内 MyUpload.prototype.createUpload = function (options) { var uploader = [], _this = this; // 判断是否有必填参数 this.expectParam(options); // 字体图标 $('head').append('<link rel="stylesheet" href="//at.alicdn.com/t/font_714144_66kol75icda.css">'); $('head').append('<link rel="stylesheet" href="./css/font.css">'); // 判断容器数量,创建DOM结构 if ($(options.dnd).length > 0) { for (var i = 0; i < $(options.dnd).length; i++) { this.establishInitDOM(options, i); } } else { this.establishInitDOM(options, 0); } if (!WebUploader.Uploader.support()) { alert('Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器'); throw new Error('WebUploader does not support the browser you are using.'); } // 调用jquery插件,查看原图 if (options.preview) { $('.gallery').magnificPopup({ delegate: 'a', // child items selector, by clicking on it popup will open type: 'image', gallery: { enabled: true } }); } $(options.dnd).each(function (index) { uploader[index] = new WebUploader.Uploader(_this.initParams(options, index)); // 当文件被加入队列之前触发 // uploader.on('beforeFileQueued', function (file) { // }); // 当一批文件添加进队列以后触发 // uploader.on('filesQueued', function (file) { // }) uploader[index].on('fileQueued', function (file) { var $li = $( '<div id="' + file.id + '" class="file-item thumbnail">' + '<a><img></a>' + '<div class="remove-this">' + '<i class="icon iconfont icon-del-copy"></i>' + '</div>' + '</div>' + '</div>' ), $img = $li.find('img'); // $list为容器jQuery实例 $('#fileList' + index).append($li); // 创建缩略图 // 如果为非图片文件,可以不用调用此方法。 // thumbnailWidth x thumbnailHeight 为 100 x 100 uploader[index].makeThumb(file, function (error, src) { if (error) { $li.find('a').attr('href', './images/no-preview.png'); $img.replaceWith('<span class="preview">上传的文件不支持预览,但不影响上传。</span><img src="./images/no-preview.png" alt="不能预览">'); return; } $img.attr('src', src); }, _this.thumbnailWidth, _this.thumbnailHeight); _this.removerFileMessage(uploader[index].options); $('#fileList' + index).on('click', '.remove-this', function () { if ($(this).parent().attr('id') == file.id) { uploader[index].removeFile(file, true); file.path = '' var result = []; $.each(successGather, function (i, n) { if (n.path !== '') { result.push(n) } }); successGather = result; $(this).parent().remove(); _this.removerFileMessage(uploader[index].options); } }); $.support.cors = true // 当文件加入队列就去请求一次token,一个文件发送一次 $.ajax({ type: 'GET', async: false, url: options.tokenPath, dataType: 'json', success: function (response) { file.token = response.token; } }); }); // 文件开始上传前 触发 // uploader.on('uploadStart', function (file) { // }); // 文件上传过程中创建进度条实时显示。 uploader[index].on('uploadProgress', function (file, percentage) { var $lis = $('#' + file.id), $percent = $lis.find('.progress span'); // 避免重复创建 if (!$percent.length) { $percent = $('<p class="progress"><span></span></p>').appendTo($lis).find('span'); } $percent.css('width', percentage * 100 + '%'); }); // 当某个文件的分块在发送前触发 block文件对象,data上传附带的参数 uploader[index].on('uploadBeforeSend', function (block, data) { // file的token赋值给data data.token = block.file.token; // 上传的安全图参数赋值给file block.file.isSafe = data.isSafe || '' }) // 文件上传成功,给item添加成功class, 用样式标记上传成功。 uploader[index].on('uploadSuccess', function (file, response) { // $('#' + file.id).addClass('upload-state-done'); var $li = $('#' + file.id), $success = $li.find('div.success'), $a = $li.find('a'); // 避免重复创建 if (!$success.length) { $success = $('<div class="success"></div>').appendTo($li); // 预览原图 if (options.preview) { if (file.isSafe) { // var $access = $('div[accessKey]').attr('accessKey').split('{')[1].split('}')[0]; var $access = $(options.access).attr('accessKey'); $a.attr('href', response.url + '?' + $access); } else { $a.attr('href', response.url); } } } file.params = response; file.path = response.path; file.uploadIndex = index; _this.successGather.push(file) if (response.statusText == '上传成功') { $success.text(response.statusText); } else { $success.text('上传失败').css({ 'color': 'red',}); $a.find('span').html('上传失败,请检查文件格式,再上传').css({ 'color': 'red', 'font-size': '12px' }); } }); // 文件上传失败,显示上传出错。 uploader[index].on('uploadError', function (file, error) { var $li = $('#' + file.id), $error = $li.find('p.error'); // 避免重复创建 if (!$error.length) { $error = $('<div class="error"></div>').appendTo($li); } $error.text('上传失败'); // console.log(file, error) }); // 完成上传完了,成功或者失败,先删除进度条。 uploader[index].on('uploadComplete', function (file) { $('#' + file.id).find('.progress').remove(); }); uploader[index].on("error", function (type) { _this.errorType(type, uploader[index].options, index); }); uploader[index].refresh(); }); } window.MyUpload = MyUpload; })(jQuery, window);
MyUpload.js
(function (jQuery, window) { function MyUpload(options) { // flash路径 this.swf = './../webuploader/Uploader.swf' // 提交文件的所有数据 this.successGather = [], // 提交文件的存储路径 this.successData = [], // 优化retina, 在retina下这个值是2 this.ratio = window.devicePixelRatio || 1, // 缩略图大小 this.thumbnailWidth = 100 * this.ratio, this.thumbnailHeight = 100 * this.ratio, // layer弹层变量 this.lay = window.layer || ""; this.options = options; this.createUpload(this.options); } // 回调方法, MyUpload.prototype.backFun = function (back) { var _this = this; if (!(typeof back === 'function')) { alert('不是一个函数'); return false; } $.each(_this.successGather, function (i, n) { if (n.path !== '') { _this.successData.push(n.params.path); _this.successData.push(n.uploadIndex) } }); back(this.successData, this.successGather); } // 判断传递进来的参数是对象, 参数是否有值初始参数之前 MyUpload.prototype.expectParam = function (params) { // 参数必须为对象 if (Object.prototype.toString.call(params) !== '[object Object]') { alert('createUpload()参数必须是对象') return false; } // 预览图片 允许空值,boolean if (typeof params.preview === 'undefined' || params.preview) { params.preview = true; $('head').append('<link rel="stylesheet" href="./../magnific-popup.css">'); $('body').append('<script type="text/javascript" src="./../jquery.magnific-popup.min.js"></script>'); } // 根据页面加载按钮样式 if (params.buttonStyle === 1) { $('head').append('<link rel="stylesheet" href="./css/imgButton.css">'); } else { $('head').append('<link rel="stylesheet" href="./css/button.css">'); } if (!(params.tokenPath) || typeof params.tokenPath !== 'string') { alert('tokenPath为空或不是为string'); return false; } if (!(params.server) || typeof params.server !== 'string') { alert('server为空或不是为string'); return false; } if (!(params.dnd) || typeof params.dnd !== 'string') { alert('dnd为空或不是为string'); return false; } } // 创建上传按钮 容器的DOM结构, 初始参数之前 MyUpload.prototype.establishInitDOM = function (options, index) { var styleDOM, $div; if (!(typeof options.dnd === 'string')) { alert('containerId不是string类型'); return false; } if (typeof options.buttonStyle === 'number') { if (options.buttonStyle === 1) { styleDOM = '<i class="iconfont icon-add1"></i>'; $div = $('<div id="fileList' + index + '"class="fileList uploader-list clear gallery"></div><div class="filePicker" id="filePicker' + index + '">' + styleDOM + '</div>'); $(options.dnd).eq(index).append($div); $(options.dnd).eq(index).addClass(options.dnd.split('.')[1] + index); } else if(options.buttonStyle === 2){ styleDOM = '选择上传图片'; $div = $('<div id="fileList' + index + '"class="fileList uploader-list clear gallery"></div><div class="filePicker" id="filePicker' + index + '">' + styleDOM + '</div>'); $(options.dnd).eq(index).append($div); $(options.dnd).eq(index).addClass(options.dnd.split('.')[1] + index); } else if (options.buttonStyle === 3) { styleDOM = '选择上传图片'; $div = $('<div class="filePicker" id="filePicker' + index + '">' + styleDOM + '</div><div id="fileList' + index + '"class="fileList uploader-list clear gallery"></div>'); $(options.dnd).eq(index).append($div); $(options.dnd).eq(index).addClass(options.dnd.split('.')[1] + index); } } else { alert('buttonStyle不是number类型') return false; } } // 超出上传数量限制隐藏上传按钮 MyUpload.prototype.removerFileMessage = function (options) { var uploaderNum = $(options.dnd).find('.file-item.thumbnail').length; if (uploaderNum >= options.fileNumLimit) { $(options.pick).hide(); } if (uploaderNum < options.fileNumLimit) { $(options.pick).show(); } } // 错误信息提示 MyUpload.prototype.errorType = function (type, options, index) { var fileNumLimit = options.fileNumLimit[index] || options.fileNumLimit, accept = options.accept[0].extensions; if (this.lay) { if (type == "Q_TYPE_DENIED") { lay.msg("请上传" + accept + "格式文件"); } else if (type == "Q_EXCEED_SIZE_LIMIT") { lay.msg("文件总大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 * options.fileNumLimit + 'MB'); } else if (type == 'Q_EXCEED_NUM_LIMIT') { lay.msg("文件超出" + fileNumLimit + "个, 自动选取位置靠前的文件") } else if (type == 'F_EXCEED_SIZE') { lay.msg("文件大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 + 'MB'); } else if (type == 'F_DUPLICATE') { alert("重复的图片、请重新上传"); } else { lay.msg("上传出错,请重新上传"); } } else { if (type == "Q_TYPE_DENIED") { alert("请上传" + accept + "格式文件"); } else if (type == "Q_EXCEED_SIZE_LIMIT") { alert("文件总大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 * options.fileNumLimit + 'MB'); } else if (type == 'Q_EXCEED_NUM_LIMIT') { alert("文件超出" + fileNumLimit + "个, 自动选取位置靠前的文件") } else if (type == 'F_EXCEED_SIZE') { alert("文件大小不能超过" + options.fileSingleSizeLimit / 1024 / 1024 + 'MB'); } else if (type == 'F_DUPLICATE') { alert("重复的图片、请重新上传"); } else { alert("上传出错,请重新上传"); } } } // 验证上传类型 MyUpload.prototype.verifyType = function (accept) { if (accept === 'images') { return { title: 'Images', extensions: 'jpg,jpeg,png,bmp', mimeTypes: 'image/jpg,image/jpeg,image/png,image/bmp' } } else if (accept === 'file') { return { title: '上传文件', extensions: 'jpg,jpeg,bmp,png,pdf,xls,xlsx,docx,zip', mimeTypes: 'image/jpg,image/bmp,image/jpeg,image/png,application/x-zip-compressed,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' } } else { return { title: 'Images', extensions: 'jpg,jpeg,png,bmp', mimeTypes: 'image/jpg,image/jpeg,image/png,image/bmp' } } } // 验证上传安全图为boolean类型还是Array 并返回值 MyUpload.prototype.verifySafe = function (params, index) { if (typeof params.isSafe === 'boolean') { return params.isSafe; } else if (Object.prototype.toString.call(params.isSafe) === '[object Array]') { if (params.isSafe[index] == false || params.isSafe[index]) { if (params.isSafe[index]) { if (!(params.access)) { alert('access为空'); } } return params.isSafe[index]; } else { return params.isSafe[0]; } } else { return false; } } // 验证上传个数为number类型还是Array 并返回值 MyUpload.prototype.verifyNum = function (params, index) { if (typeof params.fileNumLimit === 'number') { return params.fileNumLimit; } else if (Object.prototype.toString.call(params.fileNumLimit) === '[object Array]') { if (params.fileNumLimit[index]) { return params.fileNumLimit[index]; } else { return params.fileNumLimit[0] } } else { return 10; } } MyUpload.prototype.verifyDnd = function (params, index) { if (typeof params.buttonStyle === 'number' && params.buttonStyle === 1) { return params.dnd + index; } else { return '#fileList' + index; } } // 初始上传参数 MyUpload.prototype.initParams = function (params, index) { var settings = { // 自动上传 auto: true, // 拖拽容器 dnd: this.verifyDnd(params, index), // 粘贴容器 paste: params.dnd + index, // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick: '#filePicker' + index, // 禁掉页面打开图片的功能 disableGlobalDnd: true, // swf文件路径 swf: this.swf, // 文件接收服务端。 server: params.server, // 只允许选择图片文件。 accept: this.verifyType(params.accept), // method: 'GET', formData: { // 安全图片参数 isSafe: this.verifySafe(params, index) }, // 不允许重复的文件上传 duplicate: false, // 上传个数 fileNumLimit: this.verifyNum(params, index), //上传文件单个大小单位(B) fileSingleSizeLimit: params.fileSingleSizeLimit || 1 * 1024 * 1024 * 2, // 上传文件总大小单位(B) // fileSizeLimit: params.fileSingleSizeLimit || 1 * 1024 * 1024 * 2 } return settings; } // 创建上传功能,uploader方法都包含在内 MyUpload.prototype.createUpload = function (options) { var uploader = [], _this = this; // 判断是否有必填参数 this.expectParam(options); // 字体图标 $('head').append('<link rel="stylesheet" href="//at.alicdn.com/t/font_714144_66kol75icda.css">'); $('head').append('<link rel="stylesheet" href="./css/font.css">'); // 判断容器数量,创建DOM结构 if ($(options.dnd).length > 0) { for (var i = 0; i < $(options.dnd).length; i++) { this.establishInitDOM(options, i); } } else { this.establishInitDOM(options, 0); } if (!WebUploader.Uploader.support()) { alert('Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器'); throw new Error('WebUploader does not support the browser you are using.'); } // 调用jquery插件,查看原图 if (options.preview) { $('.gallery').magnificPopup({ delegate: 'a', // child items selector, by clicking on it popup will open type: 'image', gallery: { enabled: true } }); } $(options.dnd).each(function (index) { uploader[index] = new WebUploader.Uploader(_this.initParams(options, index)); // 当文件被加入队列之前触发 // uploader.on('beforeFileQueued', function (file) { // }); // 当一批文件添加进队列以后触发 // uploader.on('filesQueued', function (file) { // }) uploader[index].on('fileQueued', function (file) { var $li = $( '<div id="' + file.id + '" class="file-item thumbnail">' + '<a><img></a>' + '<div class="remove-this">' + '<i class="icon iconfont icon-del-copy"></i>' + '</div>' + '</div>' + '</div>' ), $img = $li.find('img'); // $list为容器jQuery实例 $('#fileList' + index).append($li); // 创建缩略图 // 如果为非图片文件,可以不用调用此方法。 // thumbnailWidth x thumbnailHeight 为 100 x 100 uploader[index].makeThumb(file, function (error, src) { if (error) { $li.find('a').attr('href', './images/no-preview.png'); $img.replaceWith('<span class="preview">上传的文件不支持预览,但不影响上传。</span><img src="./images/no-preview.png" alt="不能预览">'); return; } $img.attr('src', src); }, _this.thumbnailWidth, _this.thumbnailHeight); _this.removerFileMessage(uploader[index].options); $('#fileList' + index).on('click', '.remove-this', function () { if ($(this).parent().attr('id') == file.id) { uploader[index].removeFile(file, true); file.path = '' var result = []; $.each(successGather, function (i, n) { if (n.path !== '') { result.push(n) } }); successGather = result; $(this).parent().remove(); _this.removerFileMessage(uploader[index].options); } }); $.support.cors = true // 当文件加入队列就去请求一次token,一个文件发送一次 $.ajax({ type: 'GET', async: false, url: options.tokenPath, dataType: 'json', success: function (response) { file.token = response.token; } }); }); // 文件开始上传前 触发 // uploader.on('uploadStart', function (file) { // }); // 文件上传过程中创建进度条实时显示。 uploader[index].on('uploadProgress', function (file, percentage) { var $lis = $('#' + file.id), $percent = $lis.find('.progress span'); // 避免重复创建 if (!$percent.length) { $percent = $('<p class="progress"><span></span></p>').appendTo($lis).find('span'); } $percent.css('width', percentage * 100 + '%'); }); // 当某个文件的分块在发送前触发 block文件对象,data上传附带的参数 uploader[index].on('uploadBeforeSend', function (block, data) { // file的token赋值给data data.token = block.file.token; // 上传的安全图参数赋值给file block.file.isSafe = data.isSafe || '' }) // 文件上传成功,给item添加成功class, 用样式标记上传成功。 uploader[index].on('uploadSuccess', function (file, response) { // $('#' + file.id).addClass('upload-state-done'); var $li = $('#' + file.id), $success = $li.find('div.success'), $a = $li.find('a'); // 避免重复创建 if (!$success.length) { $success = $('<div class="success"></div>').appendTo($li); // 预览原图 if (options.preview) { if (file.isSafe) { // var $access = $('div[accessKey]').attr('accessKey').split('{')[1].split('}')[0]; var $access = $(options.access).attr('accessKey'); $a.attr('href', response.url + '?' + $access); } else { $a.attr('href', response.url); } } } file.params = response; file.path = response.path; file.uploadIndex = index; _this.successGather.push(file) if (response.statusText == '上传成功') { $success.text(response.statusText); } else { $success.text('上传失败').css({ 'color': 'red',}); $a.find('span').html('上传失败,请检查文件格式,再上传').css({ 'color': 'red', 'font-size': '12px' }); } }); // 文件上传失败,显示上传出错。 uploader[index].on('uploadError', function (file, error) { var $li = $('#' + file.id), $error = $li.find('p.error'); // 避免重复创建 if (!$error.length) { $error = $('<div class="error"></div>').appendTo($li); } $error.text('上传失败'); // console.log(file, error) }); // 完成上传完了,成功或者失败,先删除进度条。 uploader[index].on('uploadComplete', function (file) { $('#' + file.id).find('.progress').remove(); }); uploader[index].on("error", function (type) { _this.errorType(type, uploader[index].options, index); }); uploader[index].refresh(); }); } window.MyUpload = MyUpload; })(jQuery, window);