/*
Date: 2016/10/25
Author: hishion
Email: 506713930@qq.com
Description: html5 文件上传小插件, 支持简单验证
*/
(function(){
var Uploadify = function (){
return this.init.apply(this, arguments);
};
Uploadify.prototype ={
/*
两个参数时: form对象 与 config对象
一个参数时: config对象
*/
init: function(){
//传入的是form 与 config
if(arguments[0].tagName && arguments[0].nodeType === 1){
this.element = arguments[0];
this.setConfig(arguments[1] || {});
}else{
//传入config
this.setConfig(arguments[0]);
}
this.file = this.options['file'] || this.element && this.element.querySelector('input[type=file]');
this.url = this.options['url'] || this.element && this.element.action;
this.max = this.options['maximum'];
this.size = this.options['size'];
this.type = this.options['type'];
this.cache = {};
if(!this.file){
throw new Error("file does not exist!");
}else if(!this.url){
throw new Error("url cannot be empty!");
}else if(typeof FileReader === 'undefined'){
throw new Error('browser does not support FileReader!');
}
if(this.max > 1 && this.options.isMultiple){
this.file.setAttribute('multiple', true);
}else{
this.file.removeAttribute('multiple');
}
this.bindEvent();
},
/*
检验合法性, return null 表示无错, 否则 return 错误信息.
*/
verify: function(file){
var msg = this.options.message;
var reg = new RegExp('\\b' + this.type + '\\b');
if(file.size > this.size){
return msg['size'];
}else if(reg.test(file.type) === false){
return msg['type'];
}else if(!this.options.isAllowSame && this.cache[file.lastModifiedDate-0] === 1){
return msg['same'];
}else{
this.cache[file.lastModifiedDate-0] = 1;
return null;
}
},
/*
获得上传的个数
*/
getUploadNum: function(){
var attr, count = 0;
for(attr in this.cache){
if(this.cache[attr]){
count++;
}
}
return count;
},
/*
开始上传文件,并验证
*/
bindEvent: function(){
var self = this, opt = self.options, msg = opt.message,
cb = ['abort', 'loadstart', 'progress', 'loadend'];
function uploadstart(){
var files = this.files;
if(files.length > self.max || self.getUploadNum() >= self.max){
opt['error'](files, msg['maximum']);
}else{
for(var k = 0; k < files.length; k++){
var ret = files[k], err = self.verify(ret),
reader = new FileReader();
if(err){
opt['error'](ret, err);
}else{
switch(opt['rendAsType'].toLowerCase()){
case 'string': reader.readAsBinaryString(files[k]);break;
case 'text': reader.readAsText(files[k]);break;
default: reader.readAsDataURL(files[k]);
}
}
for(var i = 0; i < cb.length; i++){
reader.addEventListener(cb[i], opt[cb[i]], false);
}
(function(ret){
reader.addEventListener('error', function(e){
opt['error'](ret, err || msg['other']);
}, false);
reader.addEventListener('load', function(e){
self.ajaxUpload(ret);
opt['load']( e, ret);
})
}(ret));
}
}
}
if(opt.dropElement){
self.bindDropEvent(uploadstart);
}
self.on(self.file, 'change', function(){
uploadstart.call(this);
if(self.options.isAllowSame){
this.dataValue = this.value;
this.value = '';
}
});
},
/*绑定拖拽上传事件*/
bindDropEvent: function(uploadstart){
var opt = this.options;
this.on(document, 'dragenter', opt.dragenter);
this.on(document, 'dragleave', opt.dragleave);
this.on(opt.dropElement, 'dragover', function(e){
e.preventDefault();
opt.dragover.call(this, e);
});
this.on(opt.dropElement, 'drop', function(e){
e.preventDefault();
e.stopPropagation();
uploadstart.call(e.dataTransfer);
opt.drop.call(this, e);
});
},
/*ajax 上传*/
ajaxUpload: function(file){
var self = this;
var xhr = new XMLHttpRequest();
var xhrData = self.element ? new FormData(self.element) : new FormData();
xhr.lastModified = file.lastModified;
xhr.onreadystatechange = function(){
var response = this.responseText;
if(this.readyState == 4){
if(this.status < 300 && this.status >= 200){
self.options.uploadSuccess.call(this, response);
}else{
self.cache[this.lastModified] = null;
self.options.uploadFailed.call(this);
}
}
if(!this.once){
this.once = true;
self.options.uploadComplete();
}
};
xhrData.append(self.options.uploadName || self.file.name, file);
xhr.open("POST", self.url, true);
xhr.send(xhrData);
},
on: function(obj, event, callback){
return obj.addEventListener(event, callback, false);
},
setConfig: function(config){
var options = {
//input file控件对象
file: '',
//上传类型
type: 'image',
//上传最多个数
maximum: 5,
//文件大小 2M
size: 1024*1024*2,
//html5中reader对象解析类型 可选 [string | text | url]
rendAsType: 'url',
//上传时后端 接收的 name
uploadName: '',
//上传地址
url: '',
//错误提示信息!
message: {
type: '类型不对!',
size: '文件太大',
maximum: '上传文件数量太多!',
same: '不能上传相同的文件!',
other: '其它网络错误!'
},
//是否多选
isMultiple: true,
//是否允许提交重复的文件
isAllowSame: false,
//文件拖拽上传区域对象 null表示不支持
dropElement: null,
//文件拖拽dragenter事件回调
dragenter: function(){},
//文件拖拽dragleave事件回调
dragleave: function(){},
//文件拖拽dragover事件回调
dragover: function(){},
//文件拖拽drop事件回调
drop: function(){},
//ajax上传成功 回调
uploadSuccess: function(){},
//ajax上传失败 回调
uploadFailed: function(){},
//ajax上传完成
uploadComplete: function(){}
}, attr,
/*数组中 各种回调 */
cb = ['abort', 'error', 'loadstart', 'progress', 'load', 'loadend'];
for(var i = 0, len = cb.length; i < len; i++){
options[cb[i]] = function(){};
}
for(attr in config){
if(options.hasOwnProperty(attr)){
options[attr] = config[attr];
}
};
this.options = options;
}
};
window.mbUploadify = Uploadify;
}());