Last active
May 6, 2016 18:15
-
-
Save hex-ci/e6fcb0c1e6d70f4a47065f04a81ed864 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 文件上传组件 | |
// 浏览器必须支持 XMLHttpRequest 2 | |
var fileUploader = function(fileElement, userOptions) { | |
var fileEl = $(fileElement); | |
var xhrObject = null; | |
var exports = {}; | |
var hasXhr2 = window.XMLHttpRequest && ('upload' in new XMLHttpRequest()); | |
var defaultOptions = { | |
url: '', | |
maxSize: 1024 * 1024, // 最大文件大小,默认 1M | |
fileType: ['png', 'jpg', 'jpeg', 'gif'], | |
fileTypeBlacklist: [], | |
maxNumber: 1, | |
minNumber: 1, | |
auto: true, // 是否自动上传 | |
onstart: new Function(), | |
onsucceed: new Function(), | |
oncomplete: new Function(), | |
onprogress: new Function(), | |
oncancel: new Function(), | |
onerror: new Function(), | |
onend: new Function() | |
}; | |
var options = $.extend({}, defaultOptions, userOptions); | |
exports.on = function(eventName, callback) { | |
$.event.add(this, eventName, callback); | |
return this; | |
}; | |
exports.on('start', options.onstart); | |
exports.on('succeed', options.onsucceed); | |
exports.on('complete', options.oncomplete); | |
exports.on('progress', options.onprogress); | |
exports.on('cancel', options.oncancel); | |
exports.on('error', options.onerror); | |
exports.on('end', options.onend); | |
exports.options = options; | |
if (!hasXhr2) { | |
fileEl.attr('disabled', 'disabled'); | |
} | |
var uploadFile = function(el) { | |
if (!hasXhr2) { | |
return false; | |
} | |
var fd = new FormData(); | |
var files = el.files; | |
$.event.trigger('start', { | |
fileElement: el, | |
files: files | |
}, exports); | |
// 检查上传文件数量是否合法 | |
if (files.length > options.maxNumber || files.length < options.minNumber) { | |
$.event.trigger('error', { | |
error: 'number', | |
fileElement: el, | |
files: files | |
}, exports); | |
$.event.trigger('end', { | |
error: 'number', | |
fileElement: el, | |
files: files | |
}, exports); | |
return false; | |
} | |
// 检查文件类型是否合法 | |
var ext = ''; | |
var errorFiles = []; | |
for (var i = 0; i < files.length; i++) { | |
ext = files[i].name.substr((~-files[i].name.lastIndexOf(".") >>> 0) + 2); | |
if (options.fileTypeBlacklist.length > 0 && options.fileTypeBlacklist.contains(ext)) { | |
errorFiles.push(files[i]); | |
} | |
if (options.fileType.length > 0 && !options.fileType.contains(ext)) { | |
errorFiles.push(files[i]); | |
} | |
} | |
if (errorFiles.length > 0) { | |
$.event.trigger('error', { | |
error: 'type', | |
fileElement: el, | |
files: errorFiles | |
}, exports); | |
$.event.trigger('end', { | |
error: 'type', | |
fileElement: el, | |
files: files | |
}, exports); | |
return false; | |
} | |
// 检查文件长度是否合法 | |
errorFiles = []; | |
for (var i = 0; i < files.length; i++) { | |
if (files[i].size > options.maxSize) { | |
errorFiles.push(files[i]); | |
} | |
} | |
if (errorFiles.length > 0) { | |
$.event.trigger('error', { | |
error: 'size', | |
fileElement: el, | |
files: errorFiles | |
}, exports); | |
$.event.trigger('end', { | |
error: 'size', | |
fileElement: el, | |
files: files | |
}, exports); | |
return false; | |
} | |
var name = fileEl.attr('name') || 'file'; | |
if (files.length > 1) { | |
name += '[]'; | |
} | |
for (var i = 0; i < files.length; i++) { | |
fd.append(name, files[i]); | |
} | |
var xhr = new XMLHttpRequest(), | |
upload = xhr.upload; | |
upload.addEventListener("progress", function (ev) { | |
if (ev.lengthComputable) { | |
$.event.trigger('progress', { | |
fileElement: el, | |
files: files, | |
loaded: ev.loaded, | |
total: ev.total, | |
percent: (ev.loaded / ev.total) * 100 | |
}, exports); | |
} | |
}, false); | |
upload.addEventListener("load", function (ev) { | |
$.event.trigger('succeed', { | |
fileElement: el, | |
files: files | |
}, exports); | |
}, false); | |
upload.addEventListener("error", function (ev) { | |
$.event.trigger('error', { | |
error: 'upload', | |
fileElement: el, | |
files: files | |
}, exports); | |
}, false); | |
xhr.addEventListener("error", function (ev) { | |
$.event.trigger('error', { | |
error: 'download', | |
fileElement: el, | |
files: files | |
}, exports); | |
}, false); | |
xhr.addEventListener("load", function(ev) { | |
var text = ev.currentTarget.responseText; | |
var result = null; | |
result = parseJson(text); | |
if (!result) { | |
result = {'errno': 999, 'errmsg': 'Error!', data: []}; // 内部错误 | |
} | |
var errno = result.errno; | |
$.event.trigger('complete', { | |
isSuccess: (errno == 0), | |
responseData: result, | |
fileElement: el, | |
files: files | |
}, exports); | |
$.event.trigger('end', { | |
error: '', | |
fileElement: el, | |
files: files | |
}, exports); | |
}, false); | |
xhr.open("POST", options.url); | |
xhr.setRequestHeader("Cache-Control", "no-cache"); | |
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); | |
xhr.send(fd); | |
return xhr; | |
}; | |
var handler = function(e) { | |
xhrObject = uploadFile(this); | |
}; | |
var resetFile = function() { | |
// 加 form | |
fileEl.wrap('<form style="display:inline;padding:0;margin:0"></form>'); | |
fileEl.parent()[0].reset(); | |
//移除 form | |
fileEl.unwrap(); | |
}; | |
// 以 onchange 方式上传文件 | |
if (options.auto) { | |
fileEl.on('change', handler); | |
fileEl.on('click', function(){ | |
if (Browser.ie) { | |
resetFile(); | |
} | |
else { | |
setTimeout(function(){ | |
resetFile(); | |
}, 1); | |
} | |
}); | |
} | |
// 导出方法 | |
$.extend(exports, { | |
upload: function() { | |
if (fileEl.length > 0) { | |
uploadFile(fileEl[0]); | |
} | |
} | |
}); | |
return exports; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment