iframe創(chuàng)建智能表單2009-02-18 03:52:27 來(lái)源:java培訓(xùn)網(wǎng)
16.5 使用iframe創(chuàng)建智能表單使用XMLHttpRequest對(duì)象實(shí)現(xiàn)Ajax功能的好處在于XMLHttpRequest對(duì)象使用簡(jiǎn)單。只需創(chuàng)建一個(gè)XMLHttpRequest對(duì)象,,然后發(fā)送請(qǐng)求并等待服務(wù)器的響應(yīng),。不幸的是,使用JavaScript對(duì)象具有一個(gè)弊端,,即瀏覽器并不會(huì)在其歷史記錄中保存由XMLHttpRequest對(duì)象發(fā)起的HTTP請(qǐng)求,。因此,實(shí)際上XMLHttpRequest對(duì)象使得瀏覽器的Back按鈕功能失效了。 相關(guān)文章:XMLHttpRequest創(chuàng)建智能表單 實(shí)現(xiàn)智能表單的第二個(gè)解決方案就是使用一項(xiàng)早期的Ajax技術(shù),,即使用隱藏框架(frame)或隱藏內(nèi)嵌框架(iframe)來(lái)實(shí)現(xiàn)客戶(hù)端/服務(wù)器之間的通信,。為了正確地實(shí)現(xiàn)Ajax功能,必須使用兩個(gè)框架頁(yè),,其中,,一個(gè)框架頁(yè)必須是隱藏的,另一個(gè)框架頁(yè)則必須是可見(jiàn)的,。 注意: 當(dāng)使用iframe來(lái)實(shí)現(xiàn)Ajax技術(shù)時(shí),,包含iframe的頁(yè)面必須是可見(jiàn)的。 隱藏框架技術(shù)實(shí)現(xiàn)Ajax通常由4個(gè)過(guò)程組成,。第一步是由用戶(hù)的某種行為引發(fā)了一個(gè)對(duì)隱藏框架的請(qǐng)求,。這包括用戶(hù)單擊了在可見(jiàn)框架頁(yè)中的超鏈接,或者由用戶(hù)的其他交互行為所引發(fā),。通常情況下,,對(duì)隱藏框架頁(yè)的請(qǐng)求僅僅是將隱藏框架頁(yè)重定向到一個(gè)服務(wù)器上指定的服務(wù)端程序。對(duì)隱藏框架頁(yè)的重定向?qū)⒆詣?dòng)觸發(fā)第二個(gè)過(guò)程:即向服務(wù)器發(fā)送請(qǐng)求,。 在服務(wù)器程序完成了對(duì)請(qǐng)求的處理之后,,將發(fā)生第三個(gè)過(guò)程:即服務(wù)器將響應(yīng)發(fā)送回隱藏框架頁(yè)。服務(wù)器端的響應(yīng)是一個(gè)Web頁(yè)面,,該頁(yè)面將被發(fā)送給隱藏框架,。當(dāng)來(lái)自服務(wù)器的響應(yīng)被完全接收后,隱藏框架中的Web頁(yè)面將發(fā)起與可見(jiàn)框架頁(yè)的聯(lián)系,,并告知可見(jiàn)框架,,服務(wù)器的響應(yīng)已經(jīng)成功。這就是第四個(gè)過(guò)程,,該過(guò)程通常在隱藏框架的window.onload事件處理器中完成,。 這一小節(jié)中的例子將基于前一小節(jié)中所創(chuàng)建的程序。但不同的是,,我們將通過(guò)隱藏框架來(lái)實(shí)現(xiàn)瀏覽器與服務(wù)器之間的通信,。在編寫(xiě)代碼之前,我們先來(lái)討論一下從服務(wù)器將返回什么樣的數(shù)據(jù),。 注意: 下面的例子并不適用于Safari瀏覽器,,Safari瀏覽器并不會(huì)在其歷史記錄中保存iframe內(nèi)嵌框架的瀏覽歷史。 服務(wù)器將如何響應(yīng)請(qǐng)求當(dāng)我們使用XMLHttpRequest對(duì)象從服務(wù)器獲取數(shù)據(jù)時(shí),,在服務(wù)器的響應(yīng)中僅需要包含很少的關(guān)鍵字,。盡管所包含的關(guān)鍵字可能有所不同,但是服務(wù)器的響應(yīng)必須由以下兩部分組成: ● 第一是必須包含響應(yīng)的數(shù)據(jù),,而且該數(shù)據(jù)必須是HTML格式,。 ● 第二是當(dāng)iframe接收到HTML形式的響應(yīng)時(shí),必須有一個(gè)機(jī)制通知父框架頁(yè)中的文檔。 記住這兩個(gè)組成部分之后,,下面我們就來(lái)構(gòu)造服務(wù)器響應(yīng)的HTML頁(yè)面,。服務(wù)器的響應(yīng)將是一個(gè)HTML文件,該HTML文件具有如下的結(jié)構(gòu): <html> <head> <title>Returned Data</title> </head> <body> <script type="text/javascript"> //more code here </script> </body> </html> 上面的HTML頁(yè)面非常簡(jiǎn)單,,在頁(yè)面文檔中僅包含一個(gè)<script/>元素,。位于腳本塊中的JavaScript代碼將由服務(wù)器端的PHP程序生成,在這段腳本中,,將調(diào)用位于可見(jiàn)框架頁(yè)中的函數(shù)checkUsername_callBack()或者checkEmail_callBack(),,并將available或者not available作為參數(shù)傳遞給相應(yīng)的函數(shù)。例如,,下面的HTML代碼就是一個(gè)由服務(wù)器端PHP程序生成的有效的響應(yīng)頁(yè)面。 <html> <head> <title>Returned Data</title> </head> <body> <script type="text/javascript"> top.checkUsername_callBack("available", "some_username"); </script> </body> </html> 在上面有效響應(yīng)頁(yè)面的代碼中,,假定所檢查的用戶(hù)名是有效的,。因此,在該響應(yīng)頁(yè)面的腳本塊中,,調(diào)用了父窗口中的checkUsername_callBack()函數(shù),,并將字符串a(chǎn)vailable作為參數(shù)傳遞給checkUsername_callBack()函數(shù)。對(duì)于檢查用戶(hù)名或e-mail的請(qǐng)求,,相應(yīng)的響應(yīng)頁(yè)面將被發(fā)送回客戶(hù)端,。之所以要把所查找的用戶(hù)名或e-mail通過(guò)響應(yīng)頁(yè)面發(fā)送回客戶(hù)端,是為了當(dāng)用戶(hù)單擊瀏覽器的Back或Forward按鈕時(shí),,客戶(hù)端程序能夠正確地顯示輸入的用戶(hù)名或e-mail,。采用以上形式的服務(wù)器響應(yīng)頁(yè)面,可以使前例中的大部分代碼保持不變,,直接用在本例中,。
使用iframe實(shí)現(xiàn)的智能表單與前面使用XMLHttpRequest對(duì)象的例子非常類(lèi)似。而且相應(yīng)的代碼也只需進(jìn)行少量的改動(dòng),。打開(kāi)文本編輯器,,并輸入下列代碼: <html> <head> <title>Form Field Validation</title> <style type="text/css"> .fieldname { text-align: right; } .submit { text-align: right; } #hiddenFrame { display: none; } </style> <script type="text/javascript"> function checkUsername() { var userValue = document.getElementById("username").value; if (userValue == "") { alert("Please enter a user name to check!"); return; } var url = "iframe_formvalidator.php?username=" + userValue; frames["hiddenFrame"].location = url; } function checkUsername_callBack(data, userValue) { if (data == "available") { alert("The username " + userValue + " is available!"); } else { alert("We’re sorry, but " + userValue + " is not available."); } } function checkEmail() { var emailValue = document.getElementById("email").value; if (emailValue == "") { alert("Please enter an email address to check!"); return; } var url = "iframe_formvalidator.php?email=" + emailValue; frames["hiddenFrame"].location = url; } function checkEmail_callBack(data, emailValue) { if (data == "available") { alert("The email " + emailValue + " is currently not in use!"); } else { alert("We’re sorry, but " + emailValue+ " is in use by another user."); } } </script> </head> <body> <form> <table> <tr> <td class="fieldname"> Username: </td> <td> <input type="text" id="username" /> </td> <td> <a href="javascript: checkUsername()">Check Availability</a> </td> </tr> <tr> <td class="fieldname"> Email: </td> <td> <input type="text" id="email" /> </td> <td> <a href="javascript: checkEmail()">Check Availability</a> </td> </tr> <tr> <td class="fieldname"> Password: </td> <td> <input type="text" id="password" /> </td> <td /> </tr> <tr> <td class="fieldname"> Verify Password: </td> <td> <input type="text" id="password2" /> </td> <td /> </tr> <tr> <td colspan="2" class="submit"> <input type="submit" value="Submit" /> </td> <td /> </tr> </table> </form> <iframe src="about:blank" id="hiddenFrame" name="hiddenFrame" /> </body> </html> 將上面的代碼保存為validate_iframe_form.htm頁(yè)面,并將該頁(yè)面保存在Web服務(wù)器的根目錄之下,。從本書(shū)的代碼下載中查找并下載iframe_formvalidator.php文件,,并將該文件也保存在相同的目錄中。 打開(kāi)瀏覽器(非Safari的瀏覽器)并加載http://localhost/validate_iframe_form.htm頁(yè)面,。你將看到一個(gè)如圖16-7所示的頁(yè)面,。 輸入三個(gè)用戶(hù)名和e-mail地址進(jìn)行檢查。在關(guān)閉了最后一個(gè)alert對(duì)話(huà)框之后,,單擊瀏覽器的Back按鈕幾次,。你將看到你所輸入的幾個(gè)用戶(hù)名或e-mail地址的信息將按倒序出現(xiàn)。文本框中的信息并沒(méi)有發(fā)生改變,但是彈出的alert對(duì)話(huà)框?qū)@示你所輸入的用戶(hù)名和e-mail地址,。你也可以單擊瀏覽器的Forward按鈕進(jìn)行測(cè)試,。 圖 16-7 代碼解說(shuō) 在上面的HTML代碼中,除了在表單的結(jié)束標(biāo)記<form/>之后添加了一個(gè)<iframe/>元素之外,,其他的HTML元素都保持不變,。所添加的<iframe/>元素如下所示: <iframe src="about:blank" id="hiddenFrame" name="hiddenFrame" /> 該嵌入框架被初始化為一個(gè)空白的HTML頁(yè)面,其name屬性和id屬性都被設(shè)置為hiddenFrame,。在后面的代碼中,,我們將通過(guò)name屬性,從BOM對(duì)象的frames集合中引用這個(gè)嵌入框架,。接下來(lái),,設(shè)置該嵌入框架的CSS樣式。 #hiddenFrame { display: none; } 該元素規(guī)則僅包含了一個(gè)樣式聲明,,該樣式聲明將<iframe/>元素隱藏起來(lái),。 注意: 通過(guò)CSS的方式來(lái)隱藏<iframe/>元素,可以在需要調(diào)試服務(wù)器端程序時(shí)將<iframe/>元素很方便地顯示出來(lái),。 下面是頁(yè)面中的JavaScript代碼,。 function checkUsername() { var userValue = document.getElementById("username").value; if (userValue == "") { alert("Please enter a user name to check!"); return; } var url = "iframe_formvalidator.php?username=" + userValue; frames["hiddenFrame"].location = url; } 對(duì)于checkUsername()函數(shù),僅僅做了一點(diǎn)小小的修改:該函數(shù)將使用iframe而不是使用XMLHttpRequest對(duì)象來(lái)向目標(biāo)服務(wù)器發(fā)起請(qǐng)求,。在該函數(shù)中,,首先獲取了Username文本框的值。并對(duì)用戶(hù)是否在文本框中輸入了數(shù)據(jù)進(jìn)行檢查,。如果文本框?yàn)榭?,則彈出一個(gè)對(duì)話(huà)框以告訴用戶(hù)需要在Username文本框中輸入用戶(hù)名。如果Username文本框不為空,,則構(gòu)造一個(gè)向目標(biāo)服務(wù)器發(fā)送請(qǐng)求的查詢(xún)字符串,,并將該請(qǐng)求字符串的URL保存在變量url中。最后一步使用frames集合來(lái)引用該iframe,,并將其location屬性設(shè)置為url,,以在iframe中加載由url指定的服務(wù)器端頁(yè)面。 頁(yè)面中的第二個(gè)函數(shù)是checkUsername_callBack()函數(shù),,在本例中對(duì)該函數(shù)也做了少量的修改?,F(xiàn)在,該函數(shù)將接收兩個(gè)參數(shù):第一個(gè)參數(shù)data的值將是available或者not available,;第二個(gè)參數(shù)userValue的值就是在發(fā)起請(qǐng)求的查詢(xún)字符串中發(fā)送給服務(wù)器的用戶(hù)名,。checkUsername_callBack()函數(shù)的代碼如下所示: function checkUsername_callBack(data, userValue) { if (data == "available") { alert("The username " + userValue + " is available!"); } else { alert("We’re sorry, but " + userValue + " is not available."); } } 在checkUsername_callBack()函數(shù)中,首先檢查了從服務(wù)器返回的數(shù)據(jù),,即檢查data的值是否為available,。如果是,,則表示所申請(qǐng)的用戶(hù)名有效,并彈出一個(gè)對(duì)話(huà)框告訴用戶(hù)所申請(qǐng)的用戶(hù)名可用,。否則,,將彈出一個(gè)對(duì)話(huà)框,告訴用戶(hù)所申請(qǐng)的用戶(hù)名無(wú)效,。 用于檢查e-mail地址的兩個(gè)函數(shù)與之非常類(lèi)似,。下面就是用于檢查e-mail地址是否有效的兩個(gè)函數(shù):checkEmail()函數(shù)和checkEmail_callBack()函數(shù)。 function checkEmail() { var emailValue = document.getElementById("email").value; if (emailValue == "") { alert("Please enter an email address to check!"); return; } var url = "iframe_formvalidator.php?email=" + emailValue; frames["hiddenFrame"].location = url; } function checkEmail_callBack(data, emailValue) { if (data == "available") { alert("The email " + emailValue + " is currently not in use!"); } else { alert("We’re sorry, but " + emailValue + " is in use by another user."); } } checkEmail()函數(shù)的處理過(guò)程與checkUsername()函數(shù)類(lèi)似,。該函數(shù)首先獲取了Email文本框中的值,,并檢查是否為空。如果不為空,,則使用該值構(gòu)造一個(gè)發(fā)送請(qǐng)求的查詢(xún)字符串,,并在iframe中加載該URL指定的服務(wù)器頁(yè)面。 對(duì)checkEmail_callBack()函數(shù)所做修改與對(duì)checkUsername_callBack()函數(shù)所做的修改類(lèi)似,。同樣,,該函數(shù)將接收兩個(gè)參數(shù),根據(jù)從服務(wù)器返回的信息檢查用戶(hù)輸入的e-mail是否有效,,并將相應(yīng)的信息顯示給用戶(hù)。 上面這兩個(gè)例子都是比較簡(jiǎn)單的,,這兩個(gè)例子主要用于演示Ajax技術(shù)是如何工作的,。我們還可以使用其他的技術(shù)方案來(lái)實(shí)現(xiàn)智能表單(在一些技術(shù)方案中并不需要單擊超鏈接),其中一些技術(shù)方案易于實(shí)現(xiàn),,就像本章中的方案一樣,。但一些技術(shù)方案則可能比較復(fù)雜。 實(shí)際上,,Ajax技術(shù)的本質(zhì)就是:通過(guò)某種方式實(shí)現(xiàn)客戶(hù)端/服務(wù)器的通信,,而無(wú)須刷新整個(gè)頁(yè)面。實(shí)現(xiàn)Ajax技術(shù)的關(guān)鍵就是客戶(hù)端和服務(wù)器的程序,。在上面的兩個(gè)例子中,,我們可以看到,接收請(qǐng)求的服務(wù)器端程序需要處理請(qǐng)求的數(shù)據(jù),,并將處理結(jié)果返回給客戶(hù)端,。顯然,我們需要采用某種服務(wù)器端的技術(shù)來(lái)執(zhí)行所請(qǐng)求的功能,,這樣才能把Ajax技術(shù)的優(yōu)勢(shì)發(fā)揮到極致,。我們可以采用任何一種服務(wù)器端的編程技術(shù),如PHP,、ASP或 .NET,、ColdFusion,、PERL—— 本質(zhì)上我們可以采用任何一種能夠以文本格式返回?cái)?shù)據(jù)的服務(wù)器端編程技術(shù)。 |
|
來(lái)自: 昵稱(chēng)2873455 > 《我的圖書(shū)館》