日期:2014-05-16  浏览次数:20410 次

javascript实现异步提交表单或上传文件
用来异步提交表单或上传文件
使用iframe模仿ajax
代码如下:
/**
 * 用于异步提交表单
 * @author Long
 * @returns AsyncForm 
 */
var AsyncForm = (function() {
	/**
	 * @param options
	 * @param callback
	 * @returns
	 * @desc 创建iframe
	 */
	var iframe = function(options) {
		options = options || {
			id : 'iframe' + Math.random(),
			name : 'iframe',
			src : ''
		};
		var iframe;
		try {
			iframe = document.createElement('<iframe name=' + options.name+ '>');
		} catch (e) {
			iframe = document.createElement('iframe');
			iframe.name = options.name;
		}
		options.id && (iframe.id = options.id);
		iframe.src = options.src;
		iframe.style.cssText = options.cssText;
		return iframe;
	};
	var getDoc = function(frame) {
		var doc = frame.contentWindow ? frame.contentWindow.document
				: frame.contentDocument ? frame.contentDocument
						: frame.document;
		return doc;
	}

	/**
	 * @param {form}
	 * @return {}
	 * @desc 上传文件
	 */
	function AsyncForm(form) {
		var uuid = AsyncForm.uuid++;
		this.state = 0;
		// this.file = file;
		this.form = form;
		var name = 'upload_file_' + uuid;
		this.iframe = iframe({
			name : name,
			src : 'javascript:;',
			cssText : 'display:none;'
		});
		document.body.appendChild(this.iframe);
		this.form.target = name;
	};
	var callbackFunction;//回调函数
	/**
	 * 处理返回值,执行回调函数
	 * @param {e} 事件对象
	 */
	var cb=function (e){
		var doc = getDoc(this);
		var docRoot = doc.body ? doc.body : doc.documentElement;
		var responseText=eval("(" + docRoot.innerHTML + ")");
		callbackFunction(responseText,e);
		document.body.removeChild(this);
	}
	AsyncForm.uuid = 0;
	AsyncForm.prototype = {
		checkState : function() {
			var up = this;
			var iframe = getDoc(this.iframe);
			var state = iframe.readyState;//获取iframe的状态
			//检测iframe的初始化状态,若未初始化则继续检测直到初始化完成
			if (state && state.toLowerCase() == 'uninitialized')
				setTimeout(function() {up.checkState.apply(up)}, 50);
		},
		submit : function(callback) {
			callbackFunction=callback;
			var  async= this;
			//兼容IE,IE中load事件中的this指向window,使用apply指定回调函数的this对象为iframe
			if (this.iframe.attachEvent)
				this.iframe.attachEvent('onload',function(e){cb.apply(async.iframe, [e])});
			else//兼容非IE浏览器,this对象指向被绑定者本身
				this.iframe.addEventListener('load',cb, false);
			//检测iframe的状态,
			//setTimeout中执行function的this对象指向window,使用apply将function的this指向AsyncForm的实例
			setTimeout(function() {async.checkState.apply(async)}, 15);
			this.form.submit();
		},
		readyState : function() {
			return this.state;
		},
		cancel : function() {
		}
	};
	return AsyncForm;
})();



调用很简单,一句话:
new AsyncForm(form).submit(function(responseText,e){
				alert(responseText);
				window.location.href=window.location.href;
});

responseText是返回值,可以是String ,int,json 任意类型的值
这里的参数“form”是表单dom对象,submit方法的参数是一个回调函数。
今后会加入一些不使用表单直接上传文件的功能,尽请期待。
如果哪位有更好的建议欢迎提意见