修改yui3 file-html5 模块为原生代码版

作者:root
关于事件:我没用搞单独的事件机制,利用了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});
    }
};