前言:
咋一看標題還挺長的呢,還有這麼多功能,其實簡化一點就是一個功能,非同步表單提交,只是在非同步表單提交這個大功能下,可以實現圖片上傳,類比ajax技術(其實很早以前就是通過這個方式來實現多瀏覽器的相容ajax,這裡只是懷懷舊,作為一個技術來玩玩),下面的內容需要有一定的js基礎,要不然理解起來會比較困難。
注意事項:
這是我bBank裡面的一個方法,現在我把他提取出來成一個通用方法來講解。
bBank 架構介紹:http://www.cnblogs.com/bruceli/archive/2010/04/15/bBank.html
為什麼要提到bBank,因為在下面的方法中,會使用到bBank的數組的判斷,字串html轉換標準dom(我上一篇文章就介紹了這個,點擊見詳情),移除自己方法,css選取器,所以大家看到不要陌生,你可以自己寫方法來替換這些方法,也可以直接用bBank的方法,可以下載bBank看原始碼。
b$.type.isArray(args) 判斷是否是數組
b$.parseDom(strs) 字串直接轉換為標準的dom對象
b$('#bBankAsynFormSubmit_form_1b').removeSelf() 移除自己
b$() css選取器
原理:
核心是通過iframe來完成非同步。在頁面放入一個隱藏的iframe,表單有個屬性target,設定target為你要來進行非同步提交的iframe,那麼當你在提交表單的時候,其實是在使用iframe來作為提交顯示載體,頁面其它內容是無重新整理的。
其實原理很簡單,既然iframe是作為顯示載體的,那麼我們擴充下,如果提交的頁面是有傳回值的,那麼傳回值會成為iframe的body裡面的內容,在通過iframe來取得body裡面的內容來,是不是和ajax有點像,這就是以前最早用來實現非同步方法了。
ajax是時間觸發制的,既然要類比ajax,那麼我們也要觸發事件,其實也很簡單,只要使用iframe的onload裝載完成事件就可以了。
實現:
code:
var asyn = {
formSubmit: function (args, action, func) {
this.clearContext();
this.callBack = null;
this.loadHack = true;
var subArr = [];
var subArrT = [];
if (b$.type.isArray(args)) {
subArr = args;
} else {
var tag = args.tagName.toLowerCase();
if (tag == "form") { for (var i = 0, num = args.childNodes.length; i < num; i++) { subArr.push(args.childNodes[i]); } }
else { subArr = [args]; }
}
//create asyn form and ifroma
var objForm = document.createElement("form");
objForm.action = action;
objForm.target = "bBankAsynFormSubmit_iframe_1b";
objForm.encoding = "multipart/form-data";
objForm.method = "post";
objForm.id = "bBankAsynFormSubmit_form_1b";
objForm.style.display = "none";
var objIframe = b$.parseDom('<iframe id="bBankAsynFormSubmit_iframe_1b" name="bBankAsynFormSubmit_iframe_1b" src="about:blank" style="display:none;" onload="asyn.complete()"></iframe>')[0];
//add submit value in form
for (var i = 0, num = subArr.length; i < num; i++) {
if (!subArr[i].name && subArr[i].nodeType == 1 && subArr[i].tagName.toLowerCase() == "input") subArr[i].name = "bBankAsynFormSubmit_input_1b_" + i;
var input = subArr[i].cloneNode(true);
subArrT.push(input);
subArr[i].parentNode.replaceChild(input, subArr[i]);
objForm.appendChild(subArr[i]);
}
//submit
document.body.appendChild(objIframe);
document.body.appendChild(objForm);
objForm.submit();
//dispose
for (var i = 0, num = subArrT.length; i < num; i++) { subArrT[i].parentNode.replaceChild(subArr[i], subArrT[i]); }
if (func) this.callBack = func;
},
complete: function () {
if (this.loadHack && !b$.browser.isIE()) {
this.loadHack = false;
if (b$.browser.isFF()) setTimeout('asyn.complete()', 100);
return;
}
var responseText = "";
try {
var objIframe = document.getElementById("bBankAsynFormSubmit_iframe_1b");
if (objIframe.contentWindow) { responseText = objIframe.contentWindow.document.body.innerHTML; }
else { responseText = objIframe.contentDocument.document.body.innerHTML; }
} catch (err) { }
this.clearContext();
if (this.callBack) this.callBack(responseText);
},
clearContext: function () {
if (b$('#bBankAsynFormSubmit_form_1b')) b$('#bBankAsynFormSubmit_form_1b').removeSelf();
if (b$('#bBankAsynFormSubmit_iframe_1b')) b$('#bBankAsynFormSubmit_iframe_1b').removeSelf();
},
callBack: null,
loadHack: true
};
簡單講解:
其實裡面比較麻煩的應該是處理iframe的多瀏覽器安全色問題了,其實我們也不用去鑽牛角尖來討論iframe的這個相容問題,我們把相容交給瀏覽器自己來解析和解決,這裡使用了字串轉dom。
首先我建立了一個form表單和iframe,都是隱藏的,把表單的內容都轉到我建立的隱藏表單中,在把建立的隱藏表單提交。全部完成後在移除建立的表單和iframe。
使用:
asyn.formSubmit(args, action [, func]) arg:可以為一個form表單,一個input表單元素,input表單元素數組。 action:提交的url。 func:回呼函數
例:asyn.formSubmit(inputArr, 'xxx.aspx', function(d){
alert(d);
});
END
到這裡就結束了,在這裡向大家推薦一個我自己寫的js架構,上面的這個方法整合在架構裡面了
使用:b$.asyn.formSubmit(inputArr, 'xxx.aspx', function(d){
alert(d);
});
bBank 架構介紹:http://www.cnblogs.com/bruceli/archive/2010/04/15/bBank.html