改裝Juploader上傳組件,使其可以控制自由上傳

用過Juploader上傳組件的人應該對其不陌生,詳細瞭解請訪問 http://www.kudystudio.com/jUploader/index.html,這個的無刷新上傳還是比較好用的,但它有一個缺陷,就是上傳只顯示一個按鈕,選擇完文件後立即上傳,不能將上傳的工作綁定到一個元素上,進行靈活的控制,比如要實現這樣的功能:

點擊上傳按鈕,彈出文件瀏覽器選取文件,選擇好後將文件路徑顯示在文本框中,點擊“導入”按鈕進行上傳操作。
ok,無刷新上傳Juploader可以實現,但是其他的功能怎麼辦?

不用着急,我們把該組件改一下,使其即可以保持原來的功能,還可以實現你要的功能,並可對其擴展,看源碼:

/*
* jQuery jUploader 1.0
* http://www.kudystudio.com
* Author: kudy chen ([email protected])
* 
* Copyright 2012, kudy studio
* Dual licensed under the MIT or GPL Version 3 licenses.
* 
* Last Modified: 2012-03-31
*/

(function ($) {
    window.jUploader = $.jUploader = function (options) {
		
        options = $.extend({}, $.jUploader.defaults, options);
        options.id = $.jUploader.createId();
        options.uploading = false;
        var initButton = function () {
            options.button = (typeof options.button == 'string') ? $('#' + options.button) : $(options.button);
            options.button.css({
                cursor: 'pointer',
                position: 'relative',
                overflow: 'hidden',
                // Make sure browse button is in the right side in IE
                direction: 'ltr'
            })
            .addClass('jUploader-button')
            .bind('mouseover', function () {
                $(this).addClass('jUploader-button-hover');
            })
            .bind('mouseout', function () {
                $(this).removeClass('jUploader-button-hover');
            })
            .children('span').text(options.messages.upload);

            if (options.cancelable) {
                options.button.bind('click', cancel)
            }

            options.button.append(createInput());

            return options.button;
        };

        var createIframe = function () {
            var id = 'jUploaderIframe' + options.id;
            var iframe = $('<iframe id="' + id + '" name="' + id + '" src="javascript:false;" style="display:none"></iframe>').bind('load', complete);

            return iframe;
        };

        var createForm = function () {
            var id = 'jUploaderForm' + options.id;
            var form = $('<form id="' + id + '" name="' + id + '" action="' + options.action + '" target="jUploaderIframe' + options.id + '" method="post" enctype="multipart/form-data" style="display:none"></form>');

            return form;
        };
        var createInput = function () {
            // onchange="this.blur();"
            // is to aotu-rasie input file onchange event in IE(it is a bug in IE)
            var input = $('<input type="file" onchange="this.blur();" />');
			input.unbind("click");
            input
            .attr("id", 'jUploader-file' + options.id)
            .attr("name", 'jUploaderFile')
            .css({
                position: 'absolute',
                right: 0,
                top: 0,
                margin: 0,
                opacity: 0,
                padding: 0,
                fontFamily: 'Arial',
                fontSize: '118px',
                verticalAlign: 'baseline',
                cursor: 'pointer'
            })
            .bind('change', function () {
				var $_this = this;
				fileUrl = $_this.value;
				options.fileUrl = fileUrl;
				options.fileName = getFileName($_this);
				//eventType來確定如何處理事件 1.默認爲選擇完文件自動上傳 2.將上傳動作綁定到設置的按鈕上
				if(options.eventType == 1){
					//filenamed爲參數設置裏用來存放文件名的文本框
					$("#"+options.filenamed).val($('#jUploader-file' + options.id).val());
					if (validateFile($_this)) {
						//進行檢查完畢,上傳
						upload();
					}
				}else if(options.eventType == 2){
					options.fileName = getFileName($_this);
					$("#"+options.filenamed).val($('#jUploader-file' + options.id).val());
					//在參數給定的按鈕上綁定事件,點擊該按鈕會觸發上傳動作
					$("#"+options.addeventbutton).unbind('click');
					$("#"+options.addeventbutton).click(function() {  
						
						if (validateFile($_this)) {
							upload();
						}
					}); 
				}
            });

            // IE and Opera, unfortunately have 2 tab stops on file input
            // which is unacceptable in our case, disable keyboard access
            if (window.attachEvent) {
                // it is IE or Opera
                input.attr('tabIndex', "-1");
            }

            return input;
        };

        var validateFile = function (file) {
            var name = getFileName(file);

            if (!isAllowedExtension(name)) {
                showMessage('invalidExtension', name);
                return false;
            } else if (name == '') {
                showMessage('emptyFile', name);
                return false;
            }

            return true;
        };
        var getFileName = function (file) {
            // get input value and remove path to normalize
            return file.value.replace(/.*(\/|\\)/, "");
        };
        var formatFileName = function (name) {
            if (name.length > 33) {
                name = name.slice(0, 19) + '...' + name.slice(-13);
            }
            return name;
        };
        var isAllowedExtension = function (fileName) {
            var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : '';
            if (!options.allowedExtensions.length) { return true; }
            for (var i = 0; i < options.allowedExtensions.length; i++) {
                if (options.allowedExtensions[i].toLowerCase() == ext) { return true; }
            }
            return false;
        };
        var showMessage = function (type, fileName) {
            var message = options.messages[type]
            
            .replace('{file}', formatFileName(fileName))
            .replace('{extensions}', options.allowedExtensions.join(', '));

            options.showMessage(message);
        };
        var log = function (message) {
            if (options.debug && window.console) console.log('[jUploader] ' + message);
        };

        var upload = function () {
            options.uploading = true;
            options.onUpload(options.fileName);
            // prepare iframe and form for uploading
            $(document.body).append(createIframe()).append(createForm());

            // move the input to the target form
            $('#jUploader-file' + options.id)
            .attr('id', 'jUploader-file-uploading' + options.id)
            .appendTo('#jUploaderForm' + options.id);

            // create new input, and hide it for cancel event
            options.button.append(createInput().hide());
            if (options.cancelable) {
                options.button.children('span').text(options.messages.cancel);
            }

            // submit it
            $('#jUploaderForm' + options.id).get(0).submit();
        };

        var cancel = function () {
            if (options.uploading) {
                options.uploading = false;
                options.onCancel(options.fileName);
                options.button.children('span').text(options.messages.upload);
                $('#jUploaderForm' + options.id).remove();
                $('#jUploaderIframe' + options.id).attr('src', 'javascript:false;').remove();
                $('#jUploader-file' + options.id).show();
            }
        };

        var complete = function () {
            var iframe = $('#jUploaderIframe' + options.id).get(0);
            // when we remove iframe from dom
            // the request stops, but in IE load
            // event fires
            if (!iframe.parentNode) {
                return;
            }

            // fixing Opera 10.53
            if ((iframe.contentDocument &&
                iframe.contentDocument.body &&
                iframe.contentDocument.body.innerHTML == "false")
                || (iframe.contentWindow.document &&
                iframe.contentWindow.document.body &&
                iframe.contentWindow.document.body.innerHTML == "false")) {
                // In Opera event is fired second time
                // when body.innerHTML changed from false
                // to server response approx. after 1 sec
                // when we upload file with iframe
                return;
            }

            // iframe.contentWindow.document - for IE<7
            var doc = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document;
            var response;

            // fix for chrome
            if (doc.body.innerHTML == '') {
                return;
            }

            options.uploading = false;
            $('#jUploader-file' + options.id).show();
            options.button.children('span').text(options.messages.upload);

            log("innerHTML = " + doc.body.innerHTML);

            try {
                var json = doc.body.innerHTML.replace(/<pre>(.*)<\/pre>/g, '$1');
                response = eval("(" + json + ")");
            } catch (e) {
                response = {};
                //throw e;
            }

            // timeout added to fix busy state in FF3.6
            setTimeout(function () {
                $('#jUploaderForm' + options.id).remove();
                $('#jUploaderIframe' + options.id).remove();
            }, 10);

            options.onComplete(options.fileName, response);
        };

        // remind user of uploading
        $(window).bind('beforeunload', function (e) {
            if (!options.uploading)
                return;

            var e = e || window.event;
            // for ie, ff
            e.returnValue = options.messages.onLeave;
            // for webkit
            return options.messages.onLeave;
        });

        return initButton();
    };

    $.jUploader.version = 1.0;

    $.jUploader.defaults = {
        button: null,
        action: 'upload.aspx',
        allowedExtensions: [],
        cancelable: true,
        // events
        onUpload: function (fileName) { },
        onComplete: function (fileName, response) { },
        onCancel: function (fileName) { },
        // messages
        messages: {
            upload: 'Upload',
            cancel: 'Cancel',
            emptyFile: "{file} is empty, please select files again without it.",
            invalidExtension: "{file} has invalid extension. Only {extensions} are allowed.",
            onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."
        },
        showMessage: function (message) {
            alert(message);
        },
        debug: false
    };

    $.jUploader.setDefaults = function (defaults) {
        $.jUploader.defaults = $.extend({}, $.jUploader.defaults, defaults);
    };

    $.jUploader.createId = (function () {
        var id = 0;
        return function () { return ++id; };
    })();
})(jQuery);

從78行開始看,我們對其進行了改造,用一個“eventType”參數控制他的上傳動作的行爲,1.默認爲選擇完文件自動上傳 2.將上傳動作綁定到設置的按鈕上

如果我們需要將出發動作綁定到一個元素上,需要指定一個元素的id,在這裏參數爲“addeventbutton”;用來顯示文件路徑的文本框的id 參數爲“filenamed”

組件改造完畢,來看在頁面中如何使用該組件:

$.jUploader({

	button: 'upload_btn', // 這裏設置按鈕id
	action: '<?php echo site_url('role_setup/answer_import/' . $event_id);?>', // 這裏設置上傳處理接口,這個加了參數test_cancel=1來測試取消
	eventType:2,//觸發類型
	addeventbutton:'import_begin',// 要綁定事件的元素的id
	filenamed:'filename',//存放選擇的文件路徑的文本框的id
	onComplete: function (fileName, response) {

		// response是json對象,格式可以按自己的意願來定義,例子爲: { success: true, fileUrl:'' }
		if (response.success) {			
			

		} else {
			
		}
	}
  });

在傳給Juploader方法的參數中,我們增加了eventType,addeventbutton,用於存放路徑的元素的id  filenamed

大功告成!

文章轉自:http://blog.csdn.net/andy1219111/article/details/8057236
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章