使用浮動框架實現JS非同步通訊

2020-07-16 10:05:08
使用框架集設計遠端指令碼存在以下缺陷:
  • 框架集文件需要多個網頁檔案配合使用,結構不符合標準,也不利於程式碼優化。
  • 框架集缺乏靈活性,如果完全使用指令碼控制非同步請求與互動,不是很方便。

iframe 元素(浮動框架)與 frameset(框架集)功能相同,但是 <iframe> 是一個普通標籤,可以插入到頁面任意位置,不需要框架集管理,也便於 CSS 樣式和 JavaScript 指令碼控制。

操作步驟

1) 在用戶端互動頁面(main.htm)中新建函數 hideIframe(),使用該函數動態建立浮動框架,借助這個浮動框架現實與伺服器進行非同步通訊。
//建立浮動框架
//引數:url表示要請求的伺服器端檔案路徑
//返回值:無
function hideIframe (url) {
    var hideFrame = null;  //定義浮動框架變數
    hideFrame = document.createElement ("iframe");  //建立iframe元素
    hideFrame.name = "hideFrame";  //設定名稱屬性
    hideFrame.id = "hideFrame";  //設定ID屬性
    hideFrame.style.height = "0px";  //設定高度為0
    hideFrame.style.weight = "0px";  //設定寬度為0
    hideFrame.style.position = "absolute";  //設定絕對定位,避免浮動框架占據頁面空間
    hideFrame.style.visibility = "hidden";  //設定隱藏顯示
    document.body.appendChild (hideFrame);  //把浮動框架元素插入body元素中
    setTimeout (function () {  //設定延緩請求時間
        frames["hideFrame"].location.href = url;
    }, 10)
}
當使用 DOM 建立 iframe 元素時,應設定同名的 name 和 id 屬性,因為不同型別瀏覽器參照框架時分別使用 name 或 id 屬性值。當建立好 iframe 元素之後,大部分瀏覽器(如 Mozilla 和 Opera)會需要一點時間(約為幾毫秒)來識別新框架並將其新增到幀集合中,因此當載入地址準備向伺服器進行請求時,應該使用 setTimeout() 函數使傳送請求的操作延遲 10 毫秒。這樣當執行請求時,瀏覽器能夠識別這些新的框架,避免發生錯誤。

如果頁面中需要多處呼叫請求函數,則建議定義一個全域性變數,專門用來儲存浮動框架物件,這樣就可以避免每次請求時都建立新的 iframe 物件。

2) 修改用戶端互動頁面中 request() 函數的請求內容,直接呼叫 hideIframe() 函數,並傳遞 URL 引數資訊。
function request () {  //非同步請求函數
    var user = document.getElementById ("user");  //獲取使用者名稱文字方塊,注意參照路徑的不同
    var pass = document.getElementById ("pass");  //獲取密碼域,注意參照路徑的不同
    var s = "iframe_server.htm?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 {  //否則,提示錯誤資訊,並顯示表單要求重新輸入
        console.log("你輸入的使用者名稱或密碼有誤,請重新輸入");
        var user = parent.document.getElementById ("user");  //獲取文件中的使用者名稱文字方塊
        var pass = parent.document.getElementById ("pass");  //獲取文件中的密碼域
        user.value = "";  //情況文字方塊
        pass.value = "";  //清空密碼域
    }
}

3) 在伺服器端響應頁面中也應該修改參照用戶端回撥函數的路徑。
window.onload = function () {
    //...
    parent.callback (b, n);  //注意,參照路徑的變化
}
這樣通過 iframe 浮動框架只需要兩個檔案:用戶端互動頁面(main.htm)和伺服器端響應頁面(server.htm),就可以完成非同步資訊互動的任務。由於安全的原因,谷歌等瀏覽器不支援頁面之間的連續跳轉。在 IE 下,必須點選“允許阻止的內容”,方可在 IE 下正常執行。演示效果如圖所示: