关于事件:我没用搞单独的事件机制,利用了js 自带的事件注册与绑定,为了解决自定义事件的相互干扰,每组自定义事件建立单独发射节点,利用guid,像这样:this.evtNode[this.id] = document.createElement('tt');
oakFileHTML5 = function(o) {
var file = null;
if (this.isValidFile(o)) {
file = o;
}
else if (this.isValidFile(o.file)) {
file = o.file;
}
else {
file = false;
}
if (file && this.canUpload()) {
this.file = file;
this.name = file.name || file.fileName;
this.size = file.size;
this.type = file.type;
this.file = file;
this.id = this.creatID();
if (file.hasOwnProperty("lastModifiedDate")) {
this.dateModified = file.lastModifiedDate;
}
}
this.evtNode[this.id] = document.createElement('tt');
};
oakFileHTML5.prototype = {
evtNode:{},
file:null,
name:null,
size:null,
type:null,
id:null,
dateModified:null,
bytesUploaded:0,
boundEventHandler:null,
xhrWithCredentials:true,
xhrHeaders:{},
/* 文件类型检查(HTML5.File) */
isValidFile: function (file) {
return (window && window.File && file instanceof File);
},
/**
* 检查浏览器是否支持 FormData 及 XMLHttpRequest
* @method canUpload
* @static
*/
canUpload: function () {
return (window && window.FormData && window.XMLHttpRequest);
},
each: function(a,f){for(var i in a){if(a.hasOwnProperty(i)) f(a[i],i);}},
on:function(ev,fn){this.evtNode[this.id].addEventListener(ev,fn);},
detach:function(ev,fn){this.evtNode[this.id].removeEventListener(ev,fn);},
fire:function(e,o={},canBubble=false,cancelable=false){
var evt = document.createEvent("HTMLEvents");
evt.initEvent(e, canBubble, cancelable);
Object.assign(evt,o);
this.evtNode[this.id].dispatchEvent(evt);
},
creatID:function () {
var d = new Date().getTime();
var uuid = 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
});
return 'oak_'+uuid;
},
_uploadEventHandler: function (event) {
var xhr = this.xhr;
switch (event.type) {
case "progress":
this.fire("uploadprogress", {originEvent: event,
bytesLoaded: event.loaded,
bytesTotal: this.size,
percentLoaded: Math.min(100, Math.round(10000*event.loaded/this.size)/100),
file:this
});
this.bytesUploaded = event.loaded;
break;
case "load":
if (xhr.status >= 200 && xhr.status <= 299) {
this.fire("uploadcomplete", {originEvent: event,
data: event.target.responseText,file:this});
var xhrupload = xhr.upload;
xhrupload.removeEventListener ("progress", this.boundEventHandler);
xhrupload.removeEventListener ("error", this.boundEventHandler);
xhrupload.removeEventListener ("abort", this.boundEventHandler);
xhr.removeEventListener ("load", this.boundEventHandler);
xhr.removeEventListener ("error", this.boundEventHandler);
xhr.removeEventListener ("readystatechange", this.boundEventHandler);
this.xhr = null;
}
else {
this.fire("uploaderror", {originEvent: event,
data: xhr.responseText,
status: xhr.status,
statusText: xhr.statusText,
source: "http",
file:this });
}
break;
case "error":
this.fire("uploaderror", {originEvent: event,
data: xhr.responseText,
status: xhr.status,
statusText: xhr.statusText,
source: "io",file:this});
break;
case "abort":
this.fire("uploadcancel", {originEvent: event});
break;
case "readystatechange":
this.fire("readystatechange", {readyState: event.target.readyState,
originEvent: event,file:this});
break;
}
},
startUpload: function(url, parameters, fileFieldName) {
this.bytesUploaded = 0;
this.xhr = new XMLHttpRequest();
this.boundEventHandler = this._uploadEventHandler.bind(this);
var uploadData = new FormData(),
fileField = fileFieldName || "Filedata",
xhr = this.xhr,
xhrupload = this.xhr.upload,
boundEventHandler = this.boundEventHandler;
this.each(parameters, function (value, key) {uploadData.append(key, value);});
uploadData.append(fileField, this.file);
xhr.addEventListener ("loadstart", boundEventHandler, false);
xhrupload.addEventListener ("progress", boundEventHandler, false);
xhr.addEventListener ("load", boundEventHandler, false);
xhr.addEventListener ("error", boundEventHandler, false);
xhrupload.addEventListener ("error", boundEventHandler, false);
xhrupload.addEventListener ("abort", boundEventHandler, false);
xhr.addEventListener ("abort", boundEventHandler, false);
xhr.addEventListener ("loadend", boundEventHandler, false);
xhr.addEventListener ("readystatechange", boundEventHandler, false);
xhr.open("POST", url, true);
xhr.withCredentials = this.xhrWithCredentials;
this.each(this.xhrHeaders, function (value, key) {
xhr.setRequestHeader(key, value);
});
xhr.send(uploadData);
this.fire("uploadstart", {xhr: xhr});
}
};