讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議138:使用iframe實現異步通信 >

建議138:使用iframe實現異步通信

使用框架集實施異步交互存在著很多弊端:

❑一方面,頁面被深深地打上框架的烙印,不利於結構優化,瀏覽器的支持也受到很多限制,需要更多的文件配合使用。

❑另一方面,框架集缺乏靈活性,要完全使用腳本控制異步請求與交互就非常不方便。iframe與frameset(框架集)都可以實現動態加載客戶端或服務器端任何類型的網頁文件,也就是說,它們的功能相同,但表現形式各異。iframe被定義為文檔結構元素,與頁面中其他普通元素無異,完全與框架集無關,但frameset被定義為窗口元素,與html、head和body等基本文檔結構元素平行使用,可以說iframe與frameset分別屬於不同級別的元素。因此,浮動框架可以插入到頁面中的任意位置,與頁面中其他元素能夠很好地融合。同時開發人員還可以在JavaScript腳本中動態創建iframe元素並進行控制,這就給異步交互開發帶來新的活力。下面仍然以上面的示例為基礎進行擴展。

第1步,在客戶端交互頁面中新建函數hideIframe,使用該函數動態創建浮動框架,借助這個浮動框架實現與服務器進行異步通信,具體代碼如下:


//創建浮動框架

//參數:url表示要請求的服務器端文件路徑//返回值:無

function hideIframe(url){

var hideFrame=null;

hideFrame=document.createElement("iframe");

//創建iframe元素

hideFrame.name="hideFrame";

hideFrame.id="hideFrame";

hideFrame.style.;hideFrame.style.;

hideFrame.style.position="absolute";hideFrame.style.visibility="hidden";document.body.appendChild(hideFrame);setTimeout(function{

frames["hideFrame"].location.href=url;},10)

}


當使用DOM創建iframe元素時,應注意設置同名的name和id屬性,因為不同類型瀏覽器在引用框架時會分別使用name或id屬性值。在創建好iframe元素後,大部分瀏覽器(如Firefox和Opera)會需要一點時間(約為幾毫秒)來識別新框架並將其添加到幀集合中,因此,當加載地址準備向服務器進行請求時,應該使用setTimeout函數將發送請求的操作延遲10 ms。當執行請求時,瀏覽器能夠識別這些新的框架,避免發生錯誤。

如果頁面中多處需要調用請求函數,則建議定義一個全局變量,專門用來存儲浮動框架對象,這樣就可以避免每次請求時都創建新的iframe對象。

第2步,修改客戶端交互頁面中request函數的請求內容,直接調用hideIframe函數,並傳遞URL參數信息。


function request{//異步請求函數

var user=document.getElementById("user");

var pass=document.getElementById("pass");

var s="iframe_serve.html?user="+user.value+"&pass="+

pass.value;

hideIframe(s);

}


由於浮動框架與框架集屬於不同級別的作用域,浮動框架被包含在當前窗口中,所以應該使用parent而不是parent.frames[0]來調用回調函數,或者在回調函數中讀取文檔中的元素,代碼如下:


function callback(b,n){

if(b&&n){

var e=document.getElementsByTagName("body")[0];

e.innerHTML="<h1>"+n+"</h1><p>您好,歡迎登錄站點</p>";

}

else{

alert("你輸入的用戶名或密碼有誤,請重新輸入");

var user=parent.document.getElementById("user");

var pass=parent.document.getElementById("pass");

user.;

pass.;

}

}


在服務器端響應頁面中也應該修改引用客戶端回調函數的路徑,代碼如下:


window.onload=function{

//...

parent.callback(b,n);

}


這樣iframe浮動框架只需要兩個文件:客戶端交互頁面(iframe_main.html)和服務器端響應頁面(iframe_serve.html),就可以完成異步信息交互的任務。該示例的演示效果與建議137的示例相同,只不過完善了部分代碼,因此不再進行效果演示和代碼詳解。