');$io.css({位置:“绝对”,顶部:“-1000px”,左侧:“-1000 px”});}io=$io[0];xhr={//模拟对象中止:0,responseText:空,responseXML:空,状态:0,状态文本:'n/a',getAllResponseHeaders:function(){},getResponseHeader:函数(){},setRequestHeader:function(){},中止:功能(状态){var e=(status===“超时”?“超时”:“中止”);日志('中止上传…'+e);this.aborted=1;// #214if(io.contentWindow.document.execCommand){尝试{//#214io.contentWindow.document.execCommand(“停止”);}捕获(忽略){}}$io.attr('src',s.iframeSrc);//中止操作正在进行xr.error=e;if(s.error)s.error.call(s.context、xhr、e、status);如果(g)$.event.trigger(“ajaxError”,[xhr,s,e]);如果(s.complete)s.complete.call(s.context,xhr,e);}};g=s.global;//触发ajax全局事件,以便活动/块指示器正常工作如果(g&&0===$.active++){$.event.trigger(“ajaxStart”);}如果(g){$.event.trigger(“ajaxSend”,[xhr,s]);}if(s.beforeSend和s.before Send.call(s.context,xhr,s)===false){如果(s.global){$.活动--;}deferred.reject();递延收益;}if(xhr.中止){递延拒绝();递延收益;}//如果我们知道,就向数据添加提交元素sub=表格.clk;if(sub){n=子名称;if(n&&!禁用){s.extraData=s.extraData||{};s.extraData[n]=子值;if(sub.type==“图像”){s.extraData[n+'.x']=表格.clk_x;s.extraData[n+'.y']=表格.lk_y;}}}var CLIENT_TIMEOUT_ABORT=1;var SERVER_ABORT=2;函数getDoc(帧){var doc=frame.contentWindow?frame.contentWindow.document:frame.contDocument?frame.contentDocument:frame.document;返回文档;}//Rails CSRF黑客(感谢Yvan Barthelemy)var csrf_token=$('meta[name=csrf-token]').attr('content');var csrf_param=$('meta[name=csrf-param]').attr('content');if(csrf_param和csrf_token){s.extraData=s.extraData||{};s.extraData[csrf_param]=csrf_token;}//深吸一口气,以便在上传开始之前,等待重新绘制的部分cpu时间函数doSubmit(){//确保设置了表单属性var t=$form.attr(“目标”),a=$form.attr(“操作”);//以IE友好的方式更新表单属性form.setAttribute('target',id);if(!方法){form.setAttribute('method','POST');}如果(a!=s.url){form.setAttribute('action',s.url);}//ie在某些情况下设置编码时出错if(!s.skipEncodingOverride&&(!method||/post/i.test(method)){$表单属性({编码:'多部分/表单数据',enctype:'多部分/表单数据'});}//支持超时if(s.timeout){timeoutHandle=setTimeout(function(){timedOut=true;cb(CLIENT_TIMEOUT_ABORT);},s.TIMEOUT);}//查找服务器中止函数checkState(){尝试{var状态=getDoc(io).readyState;log('state='+状态);if(state&&state.toLowerCase()==“未初始化”)setTimeout(检查状态,50);}捕捉(e){log('服务器中止:',e,'(',e.name,')');cb(服务器_暂停);if(timeoutHandle)clearTimeout(timeoutHandle);timeoutHandle=未定义;}}//如果选项中提供,则将“额外”数据添加到表单var extraInputs=[];尝试{if(s.extraData){for(s.extraData中的var n){if(s.extraData.hasOwnProperty(n)){//如果使用允许多个同名值的$.param格式if($.isPlainObject(s.extraData[n])&&s.extraData[n].hasOwnProperty('name')&&.s.extraData[n].hasOwnProporty('value')){额外输入.push($('<input type=“hidden”name=“'+s.extraData[n].name+'”>').attr('value',s.extraData[n].value).appendTo(表单)[0]);}其他{额外输入.push($('<input type=“hidden”name=“'+n+'”>').attr('value',s.extraData[n]).appendTo(表单)[0]);}}}}if(!s.iframeTarget){//将iframe添加到文档并提交表单$io.appendTo(“正文”);if(io.attachEvent)io.attachEvent(“卸载”,cb);其他的io.addEventListener('load',cb,false);}setTimeout(检查状态,15);form.submit();}最后{//重置属性并删除“额外”输入元素form.setAttribute('action',a);如果(t){form.setAttribute('目标',t);}其他{$form.removeAttr(“目标”);}$(额外输入).remove();}}if(s.forceSync){doSubmit();}其他{setTimeout(doSubmit,10);//这允许dom更新渲染}var数据,doc,domCheckCount=50,callbackProcessed;函数cb(e){if(xhr.aborted | | callbackProcessed){回报;}尝试{doc=获取文档(io);}捕获(ex){log('无法访问响应文档:',ex);e=服务器暂停;}如果(e===CLIENT_TIMEOUT_ABORT&&xhr){xhr.中止(“超时”);deferred.reject(xhr,'timeout');回报;}否则,如果(e==SERVER_ABORT&&xhr){xhr.abort('服务器中止');deferred.reject(xhr,“错误”,“服务器中止”);回报;}if(!doc||doc.location.href==s.iframeSrc){//尚未收到响应if(!超时)回报;}if(io.dettachEvent)io.dettachEvent(“卸载”,cb);其他io.removeEventListener('load',cb,false);var status=“成功”,错误消息;尝试{if(超时){抛出'timeout';}var isXml=s.dataType==“xml”||doc。XMLDocument||$.isXMLDoc(doc);日志('isXml='+isXml);if(!isXml&&window.opera&&(doc.body===null||!doc.body.innerHTML)){if(--domCheckCount){//在某些浏览器(Opera)中,当//onload回调被触发,因此我们进行了一些循环以适应log('请求onLoad回调,DOM不可用');setTimeout(cb,250);回报;}//让它过去吧,因为服务器响应可能是一个空文档//log('多次尝试后无法访问iframe DOM。');//throw'DOMException:不可用';}//日志(“检测到响应”);var docRoot=doc.body?doc.body:doc.documentElement;xhr.responseText=docRoot?docRoot.innerHTML:空;xr.responseXML=文档。XML文档?文件。XML文档:doc;if(isXml)s.dataType=“xml”;xhr.getResponseHeader=函数(标头){var headers={'content-type':s.dataType};返回标题[标题];};//支持XHR“status”和“statusText”仿真:if(docRoot){xhr.status=数字(docRoot.getAttribute('status'))||xhr.sstatus;xhr.statusText=docRoot.getAttribute('statusText')||xhr.sstatusText;}var dt=(s.dataType||'').toLowerCase();var scr=/(json | script | text)/.test(dt);if(scr |s.textarea){//查看用户是否在文本区域中嵌入了响应var ta=doc.getElementsByTagName('textarea')[0];如果(ta){xhr.responseText=ta.value;//支持XHR“status”和“statusText”仿真:xhr.status=数字(ta.getAttribute('status'))||xhr.sstatus;xhr.statusText=ta.getAttribute('statusText')||xhr.sstatusText;}else if(scr){//浏览器注入前后json响应的帐户var pre=doc.getElementsByTagName('pre')[0];var b=doc.getElementsByTagName('body')[0];if(预){xhr.responseText=pre.textContent?pre.text内容:pre.innerText;}否则,如果(b){xhr.responseText=b.text内容?b.text内容:b.innerText;}}}else if(dt=='xml'&&!xhr.responseXML&&xhr.reponseText){xhr.responseXML=toXml(xhr.responseText);}尝试{数据=httpData(xhr,dt,s);}捕捉(e){status='parserror';xhr.error=错误消息=(e ||状态);}}捕捉(e){日志('error captured:',e);status=“错误”;xhr.error=错误消息=(e ||状态);}if(xhr.中止){日志('上传已中止');状态=空;}如果(xhr.status){//我们已经设置了xhr.sstatus状态=(xhr.status>=200&&xhr.sstatus<300||xhr.sStatus===304)?'成功':'错误';}//这些回调/触发器的排序很奇怪,但$.ajax就是这样做的if(状态===“成功”){如果(s.success)s.success.call(s.context,data,‘成功’,xhr);deferred.resolve(xhr.responseText,“成功”,xhr);如果(g)$.event.trigger(“ajaxSuccess”,[xhr,s]);}else if(状态){if(errMsg===未定义)errMsg=xhr.statusText;如果(s.error)s.error.call(s.context、xhr、status、errMsg);deferred.reject(xhr,'error',errMsg);如果(g)$.event.trigger(“ajaxError”,[xhr,s,errMsg]);}如果(g)$.event.trigger(“ajaxComplete”,[xhr,s]);if(g&&!--$.active){$.event.trigger(“ajaxStop”);}如果(s.complete)s.complete.call(s.context、xhr、status);callbackProcessed=true;if(s.timeout)clearTimeout(timeoutHandle);//清理setTimeout(函数(){if(!s.iframe目标)$io.remove();xhr.responseXML=空;}, 100);}var toXml=$.parseXML||函数(s,doc){//如果可用,请使用parseXML(jQuery 1.5+)if(window.ActiveXObject){doc=新ActiveXObject('Microsoft.XMLDOM');doc.async='false';doc.loadXML(s);}其他{doc=(new DOMParser()).parseFromString(s,'text/xml');}return(doc&&doc.documentElement&&doc_documentElement.nodeName!='parserror')?doc:空;};var parseJSON=$.parseJSON函数{/*jslint邪恶:真的*/返回窗口['eval']('('+s+')');};var httpData=function(xhr,type,s){//主要是从jq1.4.4中提取的var ct=xhr.getResponseHeader('content-type')||'',xml=type==='xml'||!type&&ct.indexOf('xml')>=0,data=xml?xhr.responseXML:xhr.rresponseText;if(xml&&data.documentElement.nodeName===“分析器错误”){如果($.error)$.error(“parsererror”);}if(s&&s.dataFilter){data=s.dataFilter(数据,类型);}if(数据类型===“字符串”){if(type==='json'||!type&&ct.indexOf('json')>=0){data=解析JSON(数据);}else if(type===“script”||!type&&ct.indexOf(“javascript”)>=0){$.globalEval(数据);}}返回数据;};递延收益;}};/***ajaxForm()提供了一种完全自动化表单提交的机制。**使用此方法代替ajaxSubmit()的优点是:**1:此方法将包括<input type=“image”/>元素的坐标(如果元素*用于提交表单)。* 2. 此方法将包括submit元素的名称/值数据(对于*用于提交表单)。* 3. 此方法将submit()方法绑定到表单。**ajaxForm的options参数与ajaxSubmit的工作原理完全相同。仅ajaxForm*在正确绑定submit元素和的事件后传递options参数*表单本身。*/$.fn.ajaxForm=函数(选项){options=options|{};options.delegation=选项.delegation&&$.isFunction($.fn.on);//在jQuery 1.3+中,我们可以用就绪状态修复错误if(!options.delegation&&this.length===0){var o={s:this.selector,c:this.text};if(!$.isReady&o.s){log('DOM未就绪,排队ajaxForm');$(函数(){$(o.s,o.c).ajaxForm(选项);});返回此;}//DOM准备好了吗?http://docs.jquery.com/Tutorials:简介_$(文档).ready()log('terminating;选择器'+($.isReady?'':'(DOM not ready)')找到零个元素);返回此;}if(选项.解除){$(文档).off('submit.form-plugin',this.selector,doAjaxSubmit).off('单击.form-plugin',this.selector,captureSubmittingElement).on('submit.form-plugin',this.selector,options,doAjaxSubmit).on('click.form plugin',this.selector,options,captureSubmittengElement);返回此;}返回this.ajaxFormUnbind().bind('submit.form-plugin',选项,doAjaxSubmit).bind('click.form-plugin',options,captureSubmittingElement);};//私有事件处理程序函数doAjaxSubmit(e){/*jshint validthis:true*/var选项=e.data;if(!e.isDefaultPrevented()){//如果事件已被取消,请不要继续e.预防违约();$(this).ajaxSubmit(选项);}}函数captureSubmittingElement(e){/*jshint validthis:true*/var目标=e.target;var$el=$(目标);if(!($el.is(“:提交,输入:图像”)){//这是submit el的子元素吗?(例如:按钮内的跨度)var t=$el.最接近(':submit');如果(t.长度===0){回报;}目标=t[0];}var形式=此;form.clk=目标;if(target.type==“图像”){if(e.offsetX!==未定义){form.clk_x=e.offsetX;form.clk_y=e.offsetY;}else if(类型$.fn.offset==“函数”){var偏移=$el.offset();form.clk_x=e.pageX-偏移.left;form.clk_y=e.pageY-偏移.top;}其他{form.clk_x=e.pageX-目标偏移左;form.clk_y=e.pageY-目标偏移顶部;}}//清除表单变量setTimeout(function(){form.clk=form.clk_x=form.clc_y=null;},100);}//ajaxFormUnbind解除ajaxForm绑定的事件处理程序的绑定$.fn.ajaxFormUnbind=函数(){return this.unbind('提交表单插件点击表单插件');};/***formToArray()将表单元素数据收集到可以*传递给以下任意ajax函数:$.get、$.post或load。*数组中的每个对象都有一个“name”和“value”属性。以下示例*简单登录表单的数组可能是:**[{name:“用户名”,value:“jresig”},{name:”password“,value:”secret“}]**传递给提供给*ajaxSubmit()和ajaxForm()方法。*/$.fn.formToArray=函数(语义,元素){变量a=[];如果(this.length====0){返回a;}var形式=此[0];var-els=语义?form.getElementsByTagName('*'):表单元素;if(!els){返回a;}变量i、j、n、v、el、max、jmax;对于(i=0,max=els.length;i<max;i++){el=els[i];n=el.name;如果(!n){继续;}if(semantic&&form.clk&&el.type==“image”){//当semantic==true时,动态处理图像输入如果(!el.disabled&&form.clk==el){推送({name:n,value:$(el).val(),type:el.type});推送({name:n+'.x',value:form.clkx},{name:n+'.y',value:form.clk y});}继续;}v=$.fieldValue(el,true);if(v&&v.constructor==数组){if(元素)元素。push(el);对于(j=0,jmax=v.length;j<jmax;j++){推送({name:n,value:v[j]});}}else if(feature.fileapi&&el.type==“文件”&&!el.disabled){if(元素)元素。推动(el);var文件=el.files;if(文件长度){对于(j=0;j<文件长度;j++){推送({name:n,value:files[j],type:el.type});}}其他{// #180a.push({name:n,value:'',type:el.type});}}否则如果(v!==null&&typeof v!='undefined'){if(元素)元素。push(el);推送({name:n,value:v,type:el.type,required:el.required});}}if(!semantic&&form.clk){//在元素数组中找不到输入类型==“image”!在这里处理var$input=$(form.clk),input=$input[0];n=输入名称;if(n&&!input.disabled&&input.type=='image'){推送({name:n,value:$input.val()});推送({name:n+'.x',value:form.clkx},{name:n+'.y',value:form.clk y});}}返回a;};/***将表单数据序列化为“submittable”字符串。此方法将返回字符串*格式为:name1=value1&name2=value2*/$.fn.formSerialize=函数(语义){//交给jQuery.param进行正确编码return$.param(this.formToArray(语义));};/***将jQuery对象中的所有字段元素序列化为查询字符串。*此方法将返回以下格式的字符串:name1=value1&name2=value2*/$.fn.fieldSerialize=函数(成功){变量a=[];this.each(函数(){var n=此名称;如果(!n){回报;}var v=$.fieldValue(this,successful);if(v&&v.constructor==数组){对于(var i=0,max=v.length;i<max;i++){推送({name:n,value:v[i]});}}else if(v!==null&&typeof v!='undefined'){推送({name:this.name,value:v});}});//交给jQuery.param进行正确编码返回$.param(a);};/***返回匹配集中元素的值。例如,考虑以下形式:**<表格><字段集>*<input name=“A”type=“text”/>*<input name=“A”type=“text”/>*<输入name=“B”type=“checkbox”value=“B1”/>*<input name=“B”type=“checkbox”value=“B2”/>*<input name=“C”type=“radio”value=“C1”/>*<输入name=“C”type=“radio”value=“C2”/>*</fieldset></form>**var v=$(':text').fieldValue();*//如果文本输入中没有输入值*v==['','']*//如果输入到文本输入中的值是“foo”和“bar”*v===['fo','bar']**var v=$(':checkbox').fieldValue();*//如果两个复选框都没有选中*v===未定义*//如果两个复选框都选中*v==[‘B1’,‘B2’]**var v=$(':radio').fieldValue();*//如果两个收音机都未选中*v===未定义*//如果选中第一个收音机*v==[‘C1’]**成功参数控制字段元素是否必须为“successful”*(根据http://www.w3.org/TR/html4/interactive/forms.html#successful-控件)。*成功参数的默认值为true。如果此值为false,则该值*对于每个元素,都会返回。**注意:此方法*始终*返回数组。如果无法确定有效值,则*数组将为空,否则它将包含一个或多个值。*/$.fn.fieldValue=函数(成功){对于(var val=[],i=0,max=this.length;i<max;i++){var el=这个[i];var v=$.fieldValue(el,成功);if(v===null||typeof v=='未定义'||(v.constructor==数组&&!v.length)){继续;}if(v.constructor==数组)$.merge(val,v);其他的有效推力(v);}返回值;};/***返回字段元素的值。*/$.fieldValue=函数(el,成功){var n=el.name,t=el.type,tag=el.tagName.toLowerCase();if(成功===未定义){成功=真;}if(成功&&(!n||el.disabled|t=='reset'|t=='button'||(t=='复选框'||t=='收音机')&&!el.已检查||(t=='submit'||t='image')&&el.form&&el.form.clk!=埃尔||tag==“select”&&el.selectedIndex==-1)){返回null;}if(标记==“选择”){var指数=el.selectedIndex;if(索引<0){返回null;}var a=[],ops=el.options;var one=(t==‘选择one’);var最大值=(一个索引+1:ops.length);对于(var i=(1?指数:0);i<最大值;i++){var op=操作[i];if(可选){var v=操作值;如果(!v){//给IE带来额外的痛苦。。。v=(op.attributes&&op.attibutes['value']&&!(op.aAttributes['value'].specified))?op.text:操作值;}如果(一){返回v;}a.推动(v);}}返回a;}返回$(el).val();};/***清除表单数据。对表单的输入字段执行以下操作:*-输入文本字段的“value”属性将设置为空字符串*-select元素的“selectedIndex”属性将设置为-1*-复选框和单选输入的“checked”属性将设置为false*-提交、按钮、重置和隐藏类型的输入将*不*生效*-按钮元素将*不*受影响*/$.fn.clerForm=函数(includeHidden){return this.each(function(){$('输入,选择,文本区域',this).clearFields(includeHidden);});};/***清除选定的表单元素。*/$.fn.clearFields=$.fn.clearInputs=函数(包括隐藏){var re=/^(?:color | date | datetime | email | month | number | password | range | search | tel | text | time | url | week)$/i;//'hidden”不在此列表中return this.each(function(){var t=this.type,tag=this.tagName.toLowerCase();if(re.test(t)|标记==“文本区域”){this.value=“”;}else if(t=='checkbox'||t=='收音机'){this.checked=错误;}else if(标记==“选择”){this.selectedIndex=-1;}else if(包括隐藏){//includeHidden可以是值true,也可以是选择器字符串//表示特殊测试;例如://$(“#myForm”).clearForm(“.special:hidden”)//以上操作将清除具有“special”类的隐藏输入if((includeHidden===true&&/隐藏/.test(t))||(includeHidden的类型==“字符串”&&$(this).is(incluseHidded))this.value=“”;}});};/***重置表单数据。使所有表单元素重置为其原始值。*/$.fn.resetForm=函数(){return this.each(function(){//防止名为“重置”的输入//请注意,IE将重置函数报告为“对象”if(typeof this.reset==‘function’| |(typeof thes.reset==‘object’&&!this.reset.nodeType)){this.reset();}});};/***启用或禁用任何匹配元素。*/$.fn.enable=功能(b){如果(b===未定义){b=真;}return this.each(function(){this.disabled=!b;});};/***选中/取消选中任何匹配的复选框或单选按钮,以及*选择/取消选择并匹配选项元素。*/$.fn.selected=函数(选择){if(选择===未定义){选择=true;}return this.each(function(){var t=此类型;if(t=='复选框'||t=='单选'){this.checked=选择;}else if(this.tagName.toLowerCase()==“选项”){var$sel=$(this).parent('select');if(选择&&$sel[0]&&$sel[0].type==“select-one”){//取消选择所有其他选项$sel.find('option').selected(false);}this.selected=选择;}});};//公开调试变量$.fn.ajaxSubmit.debug=假;//控制台日志记录的助手fn函数日志(){if(!$.fn.ajaxSubmit.debug)回报;var msg=“[jquery.form]”+Array.prototype.join.call(参数,“”);if(window.console&&window.console.log){window.console.log(消息);}else if(window.opera&&window.opera.postError){window.opera.postError(消息);}}})(jQuery);