mirror of https://github.com/layui/layui
842 lines
23 KiB
JavaScript
842 lines
23 KiB
JavaScript
import layui from '../core.js';
|
||
import $ from 'jquery';
|
||
import lay from './lay.js';
|
||
import { layer } from './layer.js';
|
||
|
||
/**
|
||
* upload
|
||
* 上传组件
|
||
*/
|
||
|
||
|
||
var device = layui.device();
|
||
|
||
// 模块名
|
||
var MOD_NAME = 'upload';
|
||
var MOD_INDEX = 'layui_'+ MOD_NAME +'_index'; // 模块索引名
|
||
|
||
// 外部接口
|
||
var upload = {
|
||
config: {}, // 全局配置项
|
||
index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0, // 索引
|
||
// 设置全局项
|
||
set: function(options){
|
||
var that = this;
|
||
that.config = $.extend({}, that.config, options);
|
||
return that;
|
||
},
|
||
// 事件
|
||
on: function(events, callback){
|
||
return layui.onevent.call(this, MOD_NAME, events, callback);
|
||
}
|
||
};
|
||
|
||
// 操作当前实例
|
||
var thisModule = function(){
|
||
var that = this;
|
||
var options = that.config;
|
||
var id = options.id;
|
||
|
||
thisModule.that[id] = that; // 记录当前实例对象
|
||
|
||
return {
|
||
upload: function(files){
|
||
that.upload.call(that, files);
|
||
},
|
||
reload: function(options){
|
||
that.reload.call(that, options);
|
||
},
|
||
config: that.config
|
||
}
|
||
};
|
||
|
||
var ELEM_FILE = 'layui-upload-file';
|
||
var ELEM_FORM = 'layui-upload-form';
|
||
var ELEM_IFRAME = 'layui-upload-iframe';
|
||
var ELEM_CHOOSE = 'layui-upload-choose';
|
||
var UPLOADING = 'UPLOADING';
|
||
|
||
// 构造器
|
||
var Class = function(options){
|
||
var that = this;
|
||
that.index = ++upload.index;
|
||
that.config = $.extend({}, that.config, upload.config, options);
|
||
that.render();
|
||
};
|
||
|
||
// 默认配置
|
||
Class.prototype.config = {
|
||
accept: 'images', // 允许上传的文件类型:images/file/video/audio
|
||
exts: '', // 允许上传的文件后缀名
|
||
auto: true, // 是否选完文件后自动上传
|
||
bindAction: '', // 手动上传触发的元素
|
||
url: '', // 上传地址
|
||
force: '', // 强制规定返回的数据格式,目前只支持是否强制 json
|
||
field: 'file', // 文件字段名
|
||
acceptMime: '', // 筛选出的文件类型,默认为所有文件
|
||
method: 'post', // 请求上传的 http 类型
|
||
data: {}, // 请求上传的额外参数
|
||
drag: true, // 是否允许拖拽上传
|
||
size: 0, // 文件限制大小,默认不限制
|
||
number: 0, // 允许同时上传的文件数,默认不限制
|
||
multiple: false, // 是否允许多文件上传,不支持 ie8-9
|
||
text: { // 自定义提示文本
|
||
"cross-domain": "Cross-domain requests are not supported", // 跨域
|
||
"data-format-error": "Please return JSON data format", // 数据格式错误
|
||
"check-error": "", // 文件格式校验失败
|
||
"error": "", // 上传失败
|
||
"limit-number": null, // 限制 number 属性的提示 --- function
|
||
"limit-size": null // 限制 size 属性的提示 --- function
|
||
}
|
||
};
|
||
|
||
// 重载实例
|
||
Class.prototype.reload = function(options){
|
||
var that = this;
|
||
that.config = $.extend({}, that.config, options);
|
||
that.render(true);
|
||
};
|
||
|
||
// 初始渲染
|
||
Class.prototype.render = function(rerender){
|
||
var that = this;
|
||
var options = that.config;
|
||
|
||
// 若 elem 非唯一
|
||
var elem = $(options.elem);
|
||
if (elem.length > 1) {
|
||
layui.each(elem, function() {
|
||
upload.render($.extend({}, options, {
|
||
elem: this
|
||
}));
|
||
});
|
||
return that;
|
||
}
|
||
|
||
// 合并 lay-options 属性上的配置信息
|
||
$.extend(options, lay.options(elem[0], {
|
||
attr: elem.attr('lay-data') ? 'lay-data' : null // 兼容旧版的 lay-data 属性
|
||
}));
|
||
|
||
// 若重复执行 render,则视为 reload 处理
|
||
if (!rerender && elem[0] && elem.data(MOD_INDEX)) {
|
||
var newThat = thisModule.getThis(elem.data(MOD_INDEX));
|
||
if(!newThat) return;
|
||
|
||
return newThat.reload(options);
|
||
}
|
||
|
||
options.elem = $(options.elem);
|
||
options.bindAction = $(options.bindAction);
|
||
|
||
// 初始化 id 属性 - 优先取 options > 元素 id > 自增索引
|
||
options.id = 'id' in options ? options.id : (
|
||
elem.attr('id') || that.index
|
||
);
|
||
|
||
that.file();
|
||
that.events();
|
||
};
|
||
|
||
//追加文件域
|
||
Class.prototype.file = function(){
|
||
var that = this;
|
||
var options = that.config;
|
||
var elemFile = that.elemFile = $([
|
||
'<input class="'+ ELEM_FILE +'" type="file" accept="'+ options.acceptMime +'" name="'+ options.field +'"'
|
||
,(options.multiple ? ' multiple' : '')
|
||
,'>'
|
||
].join(''));
|
||
var next = options.elem.next();
|
||
|
||
if(next.hasClass(ELEM_FILE) || next.hasClass(ELEM_FORM)){
|
||
next.remove();
|
||
}
|
||
|
||
//包裹ie8/9容器
|
||
if(device.ie && device.ie < 10){
|
||
options.elem.wrap('<div class="layui-upload-wrap"></div>');
|
||
}
|
||
|
||
that.isFile() ? (
|
||
that.elemFile = options.elem,
|
||
options.field = options.elem[0].name
|
||
) : options.elem.after(elemFile);
|
||
|
||
//初始化ie8/9的Form域
|
||
if(device.ie && device.ie < 10){
|
||
that.initIE();
|
||
}
|
||
};
|
||
|
||
//ie8-9初始化
|
||
Class.prototype.initIE = function(){
|
||
var that = this;
|
||
var options = that.config;
|
||
var iframe = $('<iframe id="'+ ELEM_IFRAME +'" class="'+ ELEM_IFRAME +'" name="'+ ELEM_IFRAME +'" frameborder="0"></iframe>');
|
||
var elemForm = $(['<form target="'+ ELEM_IFRAME +'" class="'+ ELEM_FORM +'" method="post" key="set-mine" enctype="multipart/form-data" action="'+ options.url +'">'
|
||
,'</form>'].join(''));
|
||
|
||
//插入iframe
|
||
$('#'+ ELEM_IFRAME)[0] || $('body').append(iframe);
|
||
|
||
//包裹文件域
|
||
if(!options.elem.next().hasClass(ELEM_FORM)){
|
||
that.elemFile.wrap(elemForm);
|
||
|
||
//追加额外的参数
|
||
options.elem.next('.'+ ELEM_FORM).append(function(){
|
||
var arr = [];
|
||
layui.each(options.data, function(key, value){
|
||
value = typeof value === 'function' ? value() : value;
|
||
arr.push('<input type="hidden" name="'+ key +'" value="'+ value +'">');
|
||
});
|
||
return arr.join('');
|
||
}());
|
||
}
|
||
};
|
||
|
||
//异常提示
|
||
Class.prototype.msg = function(content){
|
||
return layer.msg(content, {
|
||
icon: 2,
|
||
shift: 6
|
||
});
|
||
};
|
||
|
||
//判断绑定元素是否为文件域本身
|
||
Class.prototype.isFile = function(){
|
||
var elem = this.config.elem[0];
|
||
if(!elem) return;
|
||
return elem.tagName.toLocaleLowerCase() === 'input' && elem.type === 'file'
|
||
};
|
||
|
||
//预读图片信息
|
||
Class.prototype.preview = function(callback){
|
||
var that = this;
|
||
if(window.FileReader){
|
||
layui.each(that.chooseFiles, function(index, file){
|
||
var reader = new FileReader();
|
||
reader.readAsDataURL(file);
|
||
reader.onload = function(){
|
||
callback && callback(index, file, this.result);
|
||
};
|
||
});
|
||
}
|
||
};
|
||
|
||
// 执行上传
|
||
Class.prototype.upload = function(files, type){
|
||
var that = this;
|
||
var options = that.config;
|
||
var text = options.text || {};
|
||
var elemFile = that.elemFile[0];
|
||
|
||
// 获取文件队列
|
||
var getFiles = function(){
|
||
return files || that.files || that.chooseFiles || elemFile.files;
|
||
};
|
||
|
||
// 高级浏览器处理方式,支持跨域
|
||
var ajaxSend = function(){
|
||
var successful = 0;
|
||
var failed = 0;
|
||
var items = getFiles();
|
||
|
||
// 多文件全部上传完毕的回调
|
||
var allDone = function(){
|
||
if(options.multiple && successful + failed === that.fileLength){
|
||
typeof options.allDone === 'function' && options.allDone({
|
||
total: that.fileLength,
|
||
successful: successful,
|
||
failed: failed
|
||
});
|
||
}
|
||
};
|
||
|
||
// 发送请求
|
||
var request = function(sets){
|
||
var formData = new FormData();
|
||
|
||
// 恢复文件状态
|
||
var resetFileState = function(file) {
|
||
if (sets.unified) {
|
||
layui.each(items, function(index, file){
|
||
delete file[UPLOADING];
|
||
});
|
||
} else {
|
||
delete file[UPLOADING];
|
||
}
|
||
};
|
||
|
||
// 追加额外的参数
|
||
layui.each(options.data, function(key, value){
|
||
value = typeof value === 'function'
|
||
? sets.unified ? value() : value(sets.index, sets.file)
|
||
: value;
|
||
formData.append(key, value);
|
||
});
|
||
|
||
/*
|
||
* 添加 file 到表单域
|
||
*/
|
||
|
||
// 是否统一上传
|
||
if (sets.unified) {
|
||
layui.each(items, function(index, file){
|
||
if (file[UPLOADING]) return;
|
||
file[UPLOADING] = true; // 上传中的标记
|
||
formData.append(options.field, file);
|
||
});
|
||
} else { // 逐一上传
|
||
if (sets.file[UPLOADING]) return;
|
||
formData.append(options.field, sets.file);
|
||
sets.file[UPLOADING] = true; // 上传中的标记
|
||
}
|
||
|
||
// ajax 参数
|
||
var opts = {
|
||
url: options.url,
|
||
type: 'post', // 统一采用 post 上传
|
||
data: formData,
|
||
dataType: options.dataType || 'json',
|
||
contentType: false,
|
||
processData: false,
|
||
headers: options.headers || {},
|
||
success: function(res){ // 成功回调
|
||
options.unified ? (successful += that.fileLength) : successful++;
|
||
done(sets.index, res);
|
||
allDone(sets.index);
|
||
resetFileState(sets.file);
|
||
},
|
||
error: function(e){ // 异常回调
|
||
options.unified ? (failed += that.fileLength) : failed++;
|
||
that.msg(text['error'] || [
|
||
'Upload failed, please try again.',
|
||
'status: '+ (e.status || '') +' - '+ (e.statusText || 'error')
|
||
].join('<br>'));
|
||
error(sets.index, e.responseText, e);
|
||
allDone(sets.index);
|
||
resetFileState(sets.file);
|
||
}
|
||
};
|
||
|
||
// 进度条
|
||
if(typeof options.progress === 'function'){
|
||
opts.xhr = function(){
|
||
var xhr = $.ajaxSettings.xhr();
|
||
// 上传进度
|
||
xhr.upload.addEventListener("progress", function (obj) {
|
||
if(obj.lengthComputable){
|
||
var percent = Math.floor((obj.loaded/obj.total)* 100); // 百分比
|
||
options.progress(percent, (options.item ? options.item[0] : options.elem[0]) , obj, sets.index);
|
||
}
|
||
});
|
||
return xhr;
|
||
};
|
||
}
|
||
$.ajax(opts);
|
||
};
|
||
|
||
// 多文件是否一起上传
|
||
if(options.unified){
|
||
request({
|
||
unified: true,
|
||
index: 0
|
||
});
|
||
} else {
|
||
layui.each(items, function(index, file){
|
||
request({
|
||
index: index,
|
||
file: file
|
||
});
|
||
});
|
||
}
|
||
};
|
||
|
||
// 低版本 IE 处理方式,不支持跨域
|
||
var iframeSend = function(){
|
||
var iframe = $('#'+ ELEM_IFRAME);
|
||
|
||
that.elemFile.parent().submit();
|
||
|
||
// 获取响应信息
|
||
clearInterval(Class.timer);
|
||
Class.timer = setInterval(function() {
|
||
var res, iframeBody = iframe.contents().find('body');
|
||
try {
|
||
res = iframeBody.text();
|
||
} catch(e) {
|
||
that.msg(text['cross-domain']);
|
||
clearInterval(Class.timer);
|
||
error();
|
||
}
|
||
if(res){
|
||
clearInterval(Class.timer);
|
||
iframeBody.html('');
|
||
done(0, res);
|
||
}
|
||
}, 30);
|
||
};
|
||
|
||
// 强制返回的数据格式
|
||
var forceConvert = function(src) {
|
||
if(options.force === 'json'){
|
||
if(typeof src !== 'object'){
|
||
try {
|
||
return {
|
||
status: "CONVERTED",
|
||
data: JSON.parse(src)
|
||
};
|
||
} catch(e){
|
||
that.msg(text['data-format-error']);
|
||
return {
|
||
status: "FORMAT_ERROR",
|
||
data: {}
|
||
};
|
||
}
|
||
}
|
||
}
|
||
return { status: "DO_NOTHING", data: {} }
|
||
};
|
||
|
||
// 统一回调
|
||
var done = function(index, res){
|
||
that.elemFile.next('.'+ ELEM_CHOOSE).remove();
|
||
elemFile.value = '';
|
||
|
||
var convert = forceConvert(res);
|
||
|
||
switch(convert.status) {
|
||
case "CONVERTED":
|
||
res = convert.data;
|
||
break;
|
||
case "FORMAT_ERROR":
|
||
return;
|
||
}
|
||
|
||
typeof options.done === 'function' && options.done(res, index || 0, function(files){
|
||
that.upload(files);
|
||
});
|
||
};
|
||
|
||
// 统一网络异常回调
|
||
var error = function(index, res, xhr){
|
||
if(options.auto){
|
||
elemFile.value = '';
|
||
}
|
||
|
||
var convert = forceConvert(res);
|
||
|
||
switch(convert.status) {
|
||
case "CONVERTED":
|
||
res = convert.data;
|
||
break;
|
||
case "FORMAT_ERROR":
|
||
return;
|
||
}
|
||
|
||
typeof options.error === 'function' && options.error(index || 0, function(files){
|
||
that.upload(files);
|
||
}, res, xhr);
|
||
};
|
||
|
||
var check;
|
||
var exts = options.exts;
|
||
var value = function(){
|
||
var arr = [];
|
||
layui.each(files || that.chooseFiles, function(i, item){
|
||
arr.push(item.name);
|
||
});
|
||
return arr;
|
||
}();
|
||
|
||
// 回调函数返回的参数
|
||
var args = {
|
||
// 预览
|
||
preview: function(callback){
|
||
that.preview(callback);
|
||
},
|
||
// 上传
|
||
upload: function(index, file){
|
||
var thisFile = {};
|
||
thisFile[index] = file;
|
||
that.upload(thisFile);
|
||
},
|
||
// 追加文件到队列
|
||
pushFile: function(){
|
||
that.files = that.files || {};
|
||
layui.each(that.chooseFiles, function(index, item){
|
||
that.files[index] = item;
|
||
});
|
||
return that.files;
|
||
},
|
||
// 重置文件
|
||
resetFile: function(index, file, filename){
|
||
var newFile = new File([file], filename);
|
||
that.files = that.files || {};
|
||
that.files[index] = newFile;
|
||
},
|
||
// 获取本次选取的文件
|
||
getChooseFiles: function(){
|
||
return that.chooseFiles;
|
||
}
|
||
};
|
||
|
||
// 提交上传
|
||
var send = function(){
|
||
var ready = function(){
|
||
// IE 兼容处理
|
||
if(device.ie){
|
||
return device.ie > 9 ? ajaxSend() : iframeSend();
|
||
}
|
||
ajaxSend();
|
||
};
|
||
// 上传前的回调 - 如果回调函数明确返回 false 或 Promise.reject,则停止上传
|
||
if(typeof options.before === 'function'){
|
||
upload.util.promiseLikeResolve(options.before(args))
|
||
.then(function(result){
|
||
if(result !== false){
|
||
ready();
|
||
} else {
|
||
if(options.auto){
|
||
elemFile.value = '';
|
||
}
|
||
}
|
||
}, function(error){
|
||
if(options.auto){
|
||
elemFile.value = '';
|
||
}
|
||
error !== undefined && layui.hint().error(error);
|
||
});
|
||
}else {
|
||
ready();
|
||
}
|
||
};
|
||
|
||
// 文件类型名称
|
||
var typeName = ({
|
||
file: '文件',
|
||
images: '图片',
|
||
video: '视频',
|
||
audio: '音频'
|
||
})[options.accept] || '文件';
|
||
|
||
// 校验文件格式
|
||
value = value.length === 0
|
||
? ((elemFile.value.match(/[^\/\\]+\..+/g)||[]) || '')
|
||
: value;
|
||
|
||
// 若文件域值为空
|
||
if (value.length === 0) return;
|
||
|
||
// 根据文件类型校验
|
||
switch(options.accept){
|
||
case 'file': // 一般文件
|
||
layui.each(value, function(i, item){
|
||
if(exts && !RegExp('.\\.('+ exts +')$', 'i').test(escape(item))){
|
||
return check = true;
|
||
}
|
||
});
|
||
break;
|
||
case 'video': // 视频文件
|
||
layui.each(value, function(i, item){
|
||
if(!RegExp('.\\.('+ (exts || 'avi|mp4|wma|rmvb|rm|flash|3gp|flv') +')$', 'i').test(escape(item))){
|
||
return check = true;
|
||
}
|
||
});
|
||
break;
|
||
case 'audio': // 音频文件
|
||
layui.each(value, function(i, item){
|
||
if(!RegExp('.\\.('+ (exts || 'mp3|wav|mid') +')$', 'i').test(escape(item))){
|
||
return check = true;
|
||
}
|
||
});
|
||
break;
|
||
default: // 图片文件
|
||
layui.each(value, function(i, item){
|
||
if(!RegExp('.\\.('+ (exts || 'jpg|png|gif|bmp|jpeg|svg|webp') +')$', 'i').test(escape(item))){
|
||
return check = true;
|
||
}
|
||
});
|
||
break;
|
||
}
|
||
|
||
// 校验失败提示
|
||
if(check){
|
||
that.msg(text['check-error'] || ('选择的'+ typeName +'中包含不支持的格式'));
|
||
return elemFile.value = '';
|
||
}
|
||
|
||
// 选择文件的回调
|
||
if(type === 'choose' || options.auto){
|
||
options.choose && options.choose(args);
|
||
if(type === 'choose'){
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 检验文件数量
|
||
that.fileLength = function(){
|
||
var length = 0;
|
||
var items = getFiles();
|
||
layui.each(items, function(){
|
||
length++;
|
||
});
|
||
return length;
|
||
}();
|
||
|
||
if(options.number && that.fileLength > options.number){
|
||
return that.msg(typeof text['limit-number'] === 'function'
|
||
? text['limit-number'](options, that.fileLength)
|
||
: (
|
||
'同时最多只能上传: '+ options.number + ' 个文件'
|
||
+'<br>您当前已经选择了: '+ that.fileLength +' 个文件'
|
||
));
|
||
}
|
||
|
||
// 检验文件大小
|
||
if(options.size > 0 && !(device.ie && device.ie < 10)){
|
||
var limitSize;
|
||
|
||
layui.each(getFiles(), function(index, file){
|
||
if(file.size > 1024*options.size){
|
||
var size = options.size/1024;
|
||
size = size >= 1 ? (size.toFixed(2) + 'MB') : options.size + 'KB';
|
||
elemFile.value = '';
|
||
limitSize = size;
|
||
}
|
||
});
|
||
if(limitSize) return that.msg(typeof text['limit-size'] === 'function'
|
||
? text['limit-size'](options, limitSize)
|
||
: '文件大小不能超过 '+ limitSize);
|
||
}
|
||
|
||
send();
|
||
};
|
||
|
||
//事件处理
|
||
Class.prototype.events = function(){
|
||
var that = this;
|
||
var options = that.config;
|
||
|
||
// 设置当前选择的文件队列
|
||
var setChooseFile = function(files){
|
||
that.chooseFiles = {};
|
||
layui.each(files, function(i, item){
|
||
var time = new Date().getTime();
|
||
that.chooseFiles[time + '-' + i] = item;
|
||
});
|
||
};
|
||
|
||
// 设置选择的文本
|
||
var setChooseText = function(files, filename){
|
||
var elemFile = that.elemFile;
|
||
options.item ? options.item : options.elem;
|
||
var value = files.length > 1
|
||
? files.length + '个文件'
|
||
: ((files[0] || {}).name || (elemFile[0].value.match(/[^\/\\]+\..+/g)||[]) || '');
|
||
|
||
if(elemFile.next().hasClass(ELEM_CHOOSE)){
|
||
elemFile.next().remove();
|
||
}
|
||
that.upload(null, 'choose');
|
||
if(that.isFile() || options.choose) return;
|
||
elemFile.after('<span class="layui-inline '+ ELEM_CHOOSE +'">'+ value +'</span>');
|
||
};
|
||
|
||
/**
|
||
* 判断文件是否加入排队
|
||
* @param {File} file
|
||
* @return {boolean}
|
||
*/
|
||
var checkFile = function (file) {
|
||
var result = true;
|
||
layui.each(that.files, function (index, item) {
|
||
result = !(item.name === file.name);
|
||
if(!result) return true;
|
||
});
|
||
return result;
|
||
};
|
||
|
||
/**
|
||
* 扩展文件信息
|
||
* @template {File | FileList} T
|
||
* @param {T} obj
|
||
* @return {T}
|
||
*/
|
||
var extendInfo = function (obj) {
|
||
|
||
var extInfo = function (file) {
|
||
//文件扩展名
|
||
file.ext = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase();
|
||
// 文件大小
|
||
file.sizes = upload.util.parseSize(file.size);
|
||
// 可以继续扩展
|
||
};
|
||
|
||
//FileList对象
|
||
if (obj instanceof FileList) {
|
||
layui.each(obj, function (index, item) {
|
||
extInfo(item);
|
||
});
|
||
} else {
|
||
extInfo(obj);
|
||
}
|
||
|
||
return obj;
|
||
};
|
||
|
||
/**
|
||
* 检查获取文件
|
||
* @param {FileList} files
|
||
* @return {Array<File>|FileList}
|
||
*/
|
||
var getFiles = function (files) {
|
||
files = files || [];
|
||
if (!files.length) return [];
|
||
if (!that.files) return extendInfo(files);
|
||
var result = [];
|
||
layui.each(files, function (index, item) {
|
||
if (checkFile(item)) {
|
||
result.push(extendInfo(item));
|
||
}
|
||
});
|
||
return result;
|
||
};
|
||
|
||
// 点击上传容器
|
||
options.elem.off('upload.start').on('upload.start', function(){
|
||
var othis = $(this);
|
||
|
||
that.config.item = othis;
|
||
that.elemFile[0].click();
|
||
});
|
||
|
||
// 拖拽上传
|
||
if(!(device.ie && device.ie < 10)){
|
||
options.elem.off('upload.over').on('upload.over', function(){
|
||
var othis = $(this);
|
||
othis.attr('lay-over', '');
|
||
})
|
||
.off('upload.leave').on('upload.leave', function(){
|
||
var othis = $(this);
|
||
othis.removeAttr('lay-over');
|
||
})
|
||
.off('upload.drop').on('upload.drop', function(e, param){
|
||
var othis = $(this);
|
||
var files = getFiles(param.originalEvent.dataTransfer.files);
|
||
|
||
othis.removeAttr('lay-over');
|
||
setChooseFile(files);
|
||
|
||
options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传
|
||
});
|
||
}
|
||
|
||
// 文件选择
|
||
that.elemFile.on('change', function(){
|
||
var files = getFiles(this.files);
|
||
|
||
if(files.length === 0) return;
|
||
|
||
setChooseFile(files);
|
||
|
||
options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传
|
||
});
|
||
|
||
// 手动触发上传
|
||
options.bindAction.off('upload.action').on('upload.action', function(){
|
||
that.upload();
|
||
});
|
||
|
||
|
||
// 防止事件重复绑定
|
||
if(options.elem.data(MOD_INDEX)) return;
|
||
|
||
|
||
// 目标元素 click 事件
|
||
options.elem.on('click', function(){
|
||
if(that.isFile()) return;
|
||
$(this).trigger('upload.start');
|
||
});
|
||
|
||
// 目标元素 drop 事件
|
||
if(options.drag){
|
||
options.elem.on('dragover', function(e){
|
||
e.preventDefault();
|
||
$(this).trigger('upload.over');
|
||
}).on('dragleave', function(e){
|
||
$(this).trigger('upload.leave');
|
||
}).on('drop', function(e){
|
||
e.preventDefault();
|
||
$(this).trigger('upload.drop', e);
|
||
});
|
||
}
|
||
|
||
// 手动上传时触发上传的元素 click 事件
|
||
options.bindAction.on('click', function(){
|
||
$(this).trigger('upload.action');
|
||
});
|
||
|
||
// 绑定元素索引
|
||
options.elem.data(MOD_INDEX, options.id);
|
||
};
|
||
|
||
/**
|
||
* 上传组件辅助方法
|
||
*/
|
||
upload.util = {
|
||
/**
|
||
* 文件大小处理
|
||
* @param {number | string} size -文件大小
|
||
* @param {number} [precision] - 数值精度
|
||
* @return {string}
|
||
*/
|
||
parseSize: function (size, precision) {
|
||
precision = precision || 2;
|
||
if (null == size || !size) {
|
||
return '0';
|
||
}
|
||
var unitArr = ["Bytes", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"];
|
||
var index;
|
||
var formatSize = typeof size === 'string' ? parseFloat(size) : size;
|
||
index = Math.floor(Math.log(formatSize) / Math.log(1024));
|
||
size = formatSize / Math.pow(1024, index);
|
||
size = size % 1 === 0 ? size : parseFloat(size.toFixed(precision));//保留的小数位数
|
||
return size + unitArr[index];
|
||
},
|
||
/**
|
||
* 将给定的值转换为一个 JQueryDeferred 对象
|
||
*/
|
||
promiseLikeResolve:function(value){
|
||
var deferred = $.Deferred();
|
||
|
||
if(value && typeof value.then === 'function'){
|
||
value.then(deferred.resolve, deferred.reject);
|
||
}else {
|
||
deferred.resolve(value);
|
||
}
|
||
return deferred.promise();
|
||
}
|
||
};
|
||
|
||
// 记录所有实例
|
||
thisModule.that = {}; // 记录所有实例对象
|
||
|
||
// 获取当前实例对象
|
||
thisModule.getThis = function(id){
|
||
var that = thisModule.that[id];
|
||
if(!that) hint.error(id ? (MOD_NAME +' instance with ID \''+ id +'\' not found') : 'ID argument required');
|
||
return that;
|
||
};
|
||
|
||
// 核心入口
|
||
upload.render = function(options){
|
||
var inst = new Class(options);
|
||
return thisModule.call(inst);
|
||
};
|
||
|
||
export { upload as default, upload };
|
||
//# sourceMappingURL=upload.js.map
|