ajax編程

傳統方式校驗用戶名是否重複的設計分析javascript

RegUserUIhtml

Reguser.jspjava

RegUsernode

Main.jspjquery

註冊程序員

校驗用戶名web

是否重複面試

VerifyUserNameajax

?返回怎樣的sql

一個頁面

VerifyUserName這個Action校驗用戶名後還要回到第一個jsp頁面上,而第一個jsp頁面是第一個action顯示出來的,因此也能夠在第一個action的基礎上增長校驗用戶名的功能,這就沒有作到職責單一了,思路沒有單獨作一個VerifyUserName的action來校驗用戶名清晰。

在校驗用戶名的action和jsp頁面中要增長怎樣的代碼呢?因爲顯示結果是增長一條提示信息而已(用<div>將提示信息包起來, 有信息時顯示信息,沒信息時保持空白),因此在action中也就是要增長一條存儲提示信息的代碼,寫完action後,問題就是jsp頁面上如何實現將校驗用戶名是否存在的請求及參數提交給第一個action了,這時候必須寫javascript函數了,並應掌握<html:rewrite>標籤和document.location.href屬性。

 

傳統實現方式1 :在原來的主窗口中回顯結果

問題:

1:回顯的頁面在原來網頁效果的基礎上增長一點內容,但是服務器的響應結果會覆蓋掉窗口中原來顯示的那個網頁內容,若是服務器在響應時僅僅回送要新增的內容,則會覆蓋掉原來的整個網頁,怎樣作才能看到原來網頁效果的基礎上增長一點內容?

2:怎樣用javascript代碼將請求發送給服務器,在發送請求時,怎樣將文本框中填寫的用戶名做爲參數傳遞給服務器。

3:怎樣在<a>標籤中觸發javascript函數調用?觸發函數時要注意返回值。

實現思路:

讓VerifyUserName仍然返回Reguser.jsp,這時候須要在Reguser.jsp頁面中增長一條有時候顯示,有時候不顯示的提示信息。或者是經過生成一段javascript代碼,而後用一個彈出對話框來顯示提示信息。先用瀏覽器直接測試 VerifyUserName。

在<a>標籤中可使用javascript協議或onclick事件來觸發javascript函數調用,先用靜態數據測試一下,而後用window.location.href屬性(replace方法)或模擬表單提交的方式向服務器發送請求,把兩種方式都要作一下。

缺點:

要爲電腦增長一個鼠標,因爲瀏覽器的特色是買回鼠標就會覆蓋掉原來的電腦,因此,要想顯示出電腦加鼠標的效果,只能同時去買回一個電腦和鼠標。

比如舞臺要切換帷幕同樣,上一場的帷幕上貼的是花,當下一場要換成貼龍時,最快的方式不是把原來帷幕上的花揭下來再換上龍,而是作兩個帷幕,直接把上一個帷幕收起,同時把下一個帷幕拉開。每次都送出一個帷幕,帷幕上貼不一樣內容。

<html:base> 標籤會害你的,例如,它生成的路徑<base href=「http://localhost:8080/ajaxdemo/WEB-INF/user/RegUser.jsp」>,咱們網頁中的相對路徑全變成/Web-inf/user下面的了。雖然我在課堂上提早講了,但在練習時,不少同窗仍是都犯了這個錯誤並找不出緣由來。

 

講超連接的javascript協議時,先用這個代碼說一下:<a href=「javascript:3」></a>,讓你們明白返回值的而影響,也能夠直接在瀏覽器地址欄輸入javascript:window.document,瀏覽器將顯示[object]。

 

對於onclick的講解:

1.在保留<html:base/>標籤時,用用<a href=‘<html:rewrite action=「#’ onclick=」verifyUserName()「>作,看到<html:base/>標籤致使的錯誤後果。照理說,超連接這裏用# 不該該發送請求的,但我把jsp頁面放在web-inf裏時,瀏覽器要發請求,有同窗沒放在web-inf裏,結果沒發請求。

2.去掉<html:base/> 標籤,看到正確的效果後,

3.增長超連接,將#改成空白,即改爲以下形式:

<a href=「」 onclick=「verifyUserName()」>校驗用戶名是否存在</a>

在這裏說明清楚了若是不返回false,除了幹事件處理代碼,還幹原來默認的行爲,關於若是取消原來的行爲,看完下面的實驗後繼續講解。

4.增長超連接,讓路徑指向VerifyUserName,

<a href='<html:rewrite action="/VerifyUserName"/>' onclick="verifyUserName()">校驗用戶名是否存在</a>

這時候,即便用戶名爲zxx,也說沒有重複,這是由於瀏覽器除了訪問javascript中設置的VerifyUserName這個地址外,還執行了超連接原來的行爲,又根據href的值再次發出了請求,一共發了兩次請求,瀏覽器顯示了後面的請求的結果。

5.經過3步和第4步的問題,引出了事件處理函數中的return false的做用,能夠經過這個代碼輔助說明:<a href="delAction?id=3" onclick="return confirm('真的嗎?')">刪除</a>

 

var url = '<html:rewrite action="/AjaxVerifyUserName?username="/>' + userName;

上面的爲何要用單引號引發來才成爲javascript的字符串,不然會看成變量處理,課堂上專門演示和說明了,練習時還有同窗犯這個錯誤,我以爲關鍵是要告訴你們是檢查javascript代碼時,不能在jsp頁面檢查,而應該在其生成的網頁內容中檢查。作bs的界面時,最終的效果是瀏覽器顯示網頁而形成的,若是界面有問題,首先要查網頁的源代碼找出問題,而後才能推斷出jsp在生成網頁源代碼時出現了什麼問題,這對於不少人來講都不知道。

 

對於第2個問題:javascript是一種對它所在的網頁文檔及網頁上的各個元素進行操做的語言,便可以對網頁上的文本框進行增刪改查,如今要獲取用戶名文本框中的內容,你說怎麼辦?

 

預備的實驗內容:

<form>

用戶名:<input type="text" name="username" /><br>

密碼:<input type="password" name="password" /><br>

確認密碼:<input type="password" name="password2" /><br>

<input type="submit"  value="註冊"/>

</form>

 

校驗用戶名是否存在

 

恭喜你,用戶名未被註冊!

很遺憾,用戶名已被註冊!

 

傳統實現方式2 :用彈出的新窗口回顯結果

實現方式:在彈出窗口中回顯結果

彈出窗口演示

模態對話框演示

實現思路:

由彈出窗口打開一個網頁的方式發出校驗用戶名的請求,回送的應該是一個網頁,只是這個網頁的內容很簡單,可是,若是要有關閉按鈕,必須加上相應的按鈕和javascript代碼。

模態對話框的好處在於避免了受瀏覽器顯示新窗口的方式的差別的影響,並可要求用戶必須關閉彈出窗口後才能進行其餘操做。

特色:

服務器回送的結果給新窗口,不影響原始窗口。一個帷幕收起,同時把下一個帷幕拉開。每次都送出一個帷幕,帷幕上貼不一樣內容。

<html:base> 標籤會害你的,例如,它生成的路徑<base href=「http://localhost:8080/ajaxdemo/WEB-INF/user/RegUser.jsp」>,咱們網頁中的相對路徑全變成/Web-inf/user下面的了。雖然我在課堂上提早講了,但在練習時,不少同窗仍是都犯了這個錯誤並找不出緣由來。

 

講超連接的javascript協議時,先用這個代碼說一下:<a href=「javascript:3」></a>,讓你們明白返回值的而影響,也能夠直接在瀏覽器地址欄輸入javascript:window.document,瀏覽器將顯示[object]。

 

對於onclick的講解:

1.在保留<html:base/>標籤時,用用<a href=‘<html:rewrite action=「#’ onclick=」verifyUserName()「>作,看到<html:base/>標籤致使的錯誤後果。照理說,超連接這裏用# 不該該發送請求的,但我把jsp頁面放在web-inf裏時,瀏覽器要發請求,有同窗沒放在web-inf裏,結果沒發請求。

2.去掉<html:base/> 標籤,看到正確的效果後,

3.增長超連接,將#改成空白,即改爲以下形式:

<a href=「」 onclick=「verifyUserName()」>校驗用戶名是否存在</a>

在這裏說明清楚了若是不返回false,除了幹事件處理代碼,還幹原來默認的行爲,關於若是取消原來的行爲,看完下面的實驗後繼續講解。

4.增長超連接,讓路徑指向VerifyUserName,

<a href='<html:rewrite action="/VerifyUserName"/>' onclick="verifyUserName()">校驗用戶名是否存在</a>

這時候,即便用戶名爲zxx,也說沒有重複,這是由於瀏覽器除了訪問javascript中設置的VerifyUserName這個地址外,還執行了超連接原來的行爲,又根據href的值再次發出了請求,一共發了兩次請求,瀏覽器顯示了後面的請求的結果。

5.經過3步和第4步的問題,引出了事件處理函數中的return false的做用,能夠經過這個代碼輔助說明:<a href="delAction?id=3" onclick="return confirm('真的嗎?')">刪除</a>

 

var url = '<html:rewrite action="/AjaxVerifyUserName?username="/>' + userName;

上面的爲何要用單引號引發來才成爲javascript的字符串,不然會看成變量處理,課堂上專門演示和說明了,練習時還有同窗犯這個錯誤,我以爲關鍵是要告訴你們是檢查javascript代碼時,不能在jsp頁面檢查,而應該在其生成的網頁內容中檢查。作bs的界面時,最終的效果是瀏覽器顯示網頁而形成的,若是界面有問題,首先要查網頁的源代碼找出問題,而後才能推斷出jsp在生成網頁源代碼時出現了什麼問題,這對於不少人來講都不知道。

 

對於第2個問題:javascript是一種對它所在的網頁文檔及網頁上的各個元素進行操做的語言,便可以對網頁上的文本框進行增刪改查,如今要獲取用戶名文本框中的內容,你說怎麼辦?

 

預備的實驗內容:

<form>

用戶名:<input type="text" name="username" /><br>

密碼:<input type="password" name="password" /><br>

確認密碼:<input type="password" name="password2" /><br>

<input type="submit"  value="註冊"/>

</form>

 

校驗用戶名是否存在

 

恭喜你,用戶名未被註冊!

很遺憾,用戶名已被註冊!

 

Ajax的概念:

是asynchronous javascript and xml的簡寫。

不是一項具體的技術,而是幾門技術的綜合應用。

其核心只不過是要在javascript中調用一個叫XMLHttpRequest的javascript類,這個類能夠與Web服務器使用HTTP協議進行交互,程序不經過瀏覽器發出請求,而是用這個特殊的JavaScript對象發送請求,再由這個JavaScript對象接收響應,並將響應結果用DOM編程方式掛到原來的網頁上(見下頁的圖),從而使得javascript藉助這個api類能夠幹出比較有意義的事情。

XMLHttpRequest對象在網絡上的俗稱爲XHR對象。

 

Ajax的特色:

瀏覽器中顯示一個頁面後,這個頁面之後一直不改變,全部的操做請求都由這個網頁中的javascript代碼發出,全部的結果都由javascript代碼接受並增長到這個頁面上,瀏覽器窗口中顯示的網頁始終都是初始的那個網頁。(見下面兩頁的圖)

加強用戶體驗:能夠在用戶瀏覽網頁的同時與服務器進行異步交互和實現網頁內容的局部更新,例如,126郵箱密碼安全性判斷和google suggest;能夠按需取數據,改善頁面顯示速度,例如,樹狀菜單和babasport的首頁(整合多個信息的頁面);視覺流暢的定時刷新,例如,聊天室。(用下幾頁的圖舉例說明)

學習ajax和應用ajax的難點不在於XMLHttpRequest自己,而在於javascript和DOM編程,沒有較好的javascript和DOM編程基礎,你就很難作出有意義的ajax應用。

 

瀏覽器的普通交互方式

 

Ajax的交互方式

 

同步交互和異步交互

    舉個例子:普通B/S模式(同步)       AJAX技術(異步)

       *  同步:提交請求->等待服務器處理->處理完畢返回 這個期間客戶端瀏覽器不能幹任何事

       *   異步: 請求經過事件觸發->服務器處理(這時瀏覽器仍然能夠做其餘事情)->處理完畢

     同步是指:發送方發出數據後,等接收方發回響應之後才發下一個

                        數據包的通信方式。  異步是指:發送方發出數據後,不等接收方發回響應,接着發送下

                       個數據包的通信方式

   

     易懂的理解:

     異步傳輸:   你傳輸吧,我去作個人事了,傳輸完了告訴我一聲   同步傳輸:   你如今傳輸,我要親眼看你傳輸完成,纔去作別的事

 

AJAX案例之google suggest

AJAX案例之Google Maps

Ajax的應用場景:財富通網吧充值界面

Ajax的應用場景:密碼安全性檢測

Ajax的應用場景:RIA應用

Ajax的應用場景:郵箱系統

Ajax的應用場景:藍源批發零售業連鎖管理系統

 

究竟什麼是Ajax

Ajax:一種不用刷新整個頁面即可與服務器通信的辦法

圖1 Web的傳統模型。客戶端向服務器發送一個請求,服務器返回整個頁面,如此反覆

圖2 在Ajax模型中,數據在客戶端與服務器之間獨立傳輸。服務器再也不返回整個頁面

 

Ajax的實現方式

不用刷新整個頁面即可與服務器通信的辦法:

Flash

Java applet

框架:若是使用一組框架構造了一個網頁,能夠只更新其中一個框架,而沒必要驚動整個頁面

隱藏的iframe

XMLHttpRequest:該對象是對 JavaScript 的一個擴展,可以使網頁與服務器進行通訊。是建立 Ajax 應用的最佳選擇。實際上一般把 Ajax 當成 XMLHttpRequest 對象的代名詞

 

Ajax的工做原理

Ajax的核心是JavaScript對象XmlHttpRequest。

    該對象在Internet Explorer 5中首次引入,它是一種支持異步請求的技術。簡而言之,XmlHttpRequest使您可使用JavaScript向服務器提出請求並處理響應,而不阻塞用戶。

AJAX採用異步交互過程。AJAX在用戶與服務器之間引入一箇中間媒介,從而消除了網絡交互過程當中的處理—等待—處理—等待缺點。

用戶的瀏覽器在執行任務時即裝載了AJAX引擎。AJAX引擎用JavaScript語言編寫,一般藏在一個隱藏的框架中。它負責編譯用戶界面及與服務器之間的交互。

AJAX引擎容許用戶與應用軟件之間的交互過程異步進行,獨立於用戶與網絡服務器間的交流。如今,能夠用Javascript調用AJAX引擎來代替產生一個HTTP的用戶動做,內存中的數據編輯、頁面導航、數據校驗這些不須要從新載入整個頁面的需求能夠交給AJAX來執行。

使用AJAX,能夠爲JSP、開發人員、終端用戶帶來可見的便捷:

用戶界面

AJAX引擎

服務器

用戶界面

服務器

 

AJAX包含的技術

      AJAX:(Asynchronous JavaScript and XML)並非一項新技術,實際上是多種技術的綜合,包括Javascript、XHTML和CSS、DOM、XML和XMLHttpRequest.

服務器端語言:服務器須要具有向瀏覽器發送特定信息的能力。Ajax與服務器端語言無關。

XML (eXtensible Markup Language,可擴展標記語言) 是一種描述數據的格式。AJAX 程序須要某種格式化的格式來在服務器和客戶端之間傳遞信息,XML 是其中的一種選擇

XHTML(eXtended Hypertext Markup Language,使用擴展超媒體標記語言)和 CSS(Cascading Style Sheet,級聯樣式單)標準化呈現;

DOM(Document Object Model,文檔對象模型)實現動態顯示和交互;

使用XMLHTTP組件XMLHttpRequest對象進行異步數據讀取

使用JavaScript綁定和處理全部數據

 

AJAX的缺陷

AJAX不是完美的技術。也存在缺陷:

1    AJAX大量使用了Javascript和AJAX引擎,而這個取決於瀏覽器的支持。IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持,Mozilla雖然也支持AJAX,可是提供XMLHttpRequest的方式不同。因此,使用AJAX的程序必須測試針對各個瀏覽器的兼容性。

2   AJAX更新頁面內容的時候並無刷新整個頁面,所以,網頁的後退功能是失效的;有的用戶還常常搞不清楚如今的數據是舊的仍是已經更新過的。這個就須要在明顯位置提醒用戶「數據已更新」。

3    對流媒體的支持沒有FLASH、Java Applet好。

4    一些手持設備(如手機、PDA等)如今還不能很好的支持Ajax。

 

XMLHttpRequest對象   XMLHttpRequest是XMLHTTP組件的對象,經過這個對象,AJAX能夠像桌面應用程序同樣只同服務器進行數據層面的交換,而不用每次都刷新界面,也不用每次將數據處理的工做都交給服務器來作;這樣既減輕了服務器負擔又加快了響應速度、縮短了用戶等待的時間。

XMLHttpRequest最先是在IE5中以ActiveX組件的形式實現的。非W3C標準.

建立XMLHttpRequest對象(因爲非標準因此實現方法不統一)

Internet Explorer把XMLHttpRequest實現爲一個ActiveX對象

其餘瀏覽器(Firefox、Safari、Opera…)把它實現爲一個本地的JavaScript對象。

XMLHttpRequest在不一樣瀏覽器上的實現是兼容的,因此能夠用一樣的方式訪問XMLHttpRequest實例的屬性和方法,而不論這個實例建立的方法是什麼。

 

XMLHttpRequest對象初始化

function   createXmlHttpRequest(){

var xmlhttp = null;

try{

                   //Firefox, Opera 8.0+, Safari

           xmlhttp=new XMLHttpRequest();

                   }catch(e){//IEIE7.0如下的瀏覽器以ActiveX組件的方式來建立XMLHttpRequest對象

var MSXML =

['MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0',

'MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0',

'MSXML2.XMLHTTP','Microsoft.XMLHTTP'];

  for(var n = 0; n < MSXML.length; n ++){

    try{

      xmlhttp = new ActiveXObject(MSXML[n]);

      break;

    }catch(e){}}

  }

return xmlhttp;

}

 

XMLHttpRequest對象方法

方法

描述

abort()

中止當前請求

getAllResponseHeaders()

把http請求的全部響應首部做爲鍵/值對返回

getResponseHeader("headerLabel")

返回指定首部的串值

open(「method」,」url」)

創建對服務器的調用,method參數能夠是GET,POST。url參數能夠是相對URL或絕對URL。這個方法還包括3個可選參數。

send(content)

向服務器發送請求

setRequestHeader("label", "value")

把指定首部設置爲所提供的值。在設置任何首部以前必須先調用open()

 

XMLHttpRequest對象屬性

發送請求--方法和屬性介紹

利用XMLHttpRequest 實例與服務器進行通訊包含如下3個關鍵部分:

onreadystatechange 事件處理函數

open 方法

send 方法

 

onreadystatechange:

該事件處理函數由服務器觸發,而不是用戶

在 Ajax 執行過程當中,服務器會通知客戶端當前的通訊狀態。這依靠更新 XMLHttpRequest 對象的 readyState 來實現。改變 readyState 屬性是服務器對客戶端鏈接操做的一種方式。

每次 readyState 屬性的改變都會觸發 readystatechange事件

 

open(method, url, asynch)

XMLHttpRequest 對象的 open 方法容許程序員用一個Ajax調用向服務器發送請求。

method:請求類型,相似 「GET」或」POST」的字符串。若只想從服務器檢索一個文件,而不須要發送任何數據,使用GET(能夠在GET請求裏經過附加在URL上的查詢字符串來發送數據,不過數據大小限制爲2000個字符)。若須要向服務器發送數據,用POST。

在某些狀況下,有些瀏覽器會把多個XMLHttpRequest請求的結果緩存在同一個URL。若是對每一個請求的響應不一樣,這就會帶來很差的結果。把當前時間戳追加到URL的最後,就能確保URL的唯一性,從而避免瀏覽器緩存結果。

 

url:路徑字符串,指向你所請求的服務器上的那個文件。能夠是絕對路徑或相對路徑。

asynch:表示請求是否要異步傳輸,默認值爲true(異步)。指定true,在讀取後面的腳本以前,不須要等待服務器的相應。指定false,當腳本處理過程通過這點時,會停下來,一直等到Ajax請求執行完畢再繼續執行。

var url = "GetAndPostExample?timeStamp=" + new Date().getTime();

 

send(data)

open 方法定義了 Ajax 請求的一些細節。send 方法可爲已經待命的請求發送指令

data:將要傳遞給服務器的字符串。

若選用的是 GET 請求,則不會發送任何數據, 給 send 方法傳遞 null 便可:request.send(null);

當向send()方法提供參數時,要確保open()中指定的方法是POST,若是沒有數據做爲請求體的一部分發送,則使用null.

完整的 Ajax 的 GET 請求示例:

使用get請求時send方法參數時null,若是傳值的話,服務器也接受不到

 

setRequestHeader(header,value)

當瀏覽器向服務器請求頁面時,它會伴隨這個請求發送一組首部信息。這些首部信息是一系列描述請求的元數據(metadata)。首部信息用來聲明一個請求是 GET 仍是 POST。

Ajax 請求中,發送首部信息的工做能夠由 setRequestHeader完成

參數header: 首部的名字;  參數value:首部的值。

若是用 POST 請求向服務器發送數據,須要將 「Content-type」 的首部設置爲 「application/x-www-form-urlencoded」.它會告知服務器正在發送數據,而且數據已經符合URL編碼了。

該方法必須在open()以後才能調用

完整的 Ajax 的 POST 請求示例:

 

用 XMLHttpRequest 的方法可向服務器發送請求。在 Ajax 處理過程當中,XMLHttpRequest 的以下屬性可被服務器更改:

readyState

status

responseText

responseXML

 

readyState

readyState 屬性表示Ajax請求的當前狀態。它的值用數字表明。

0 表明未初始化。 尚未調用 open 方法

1 表明正在加載。 open 方法已被調用,但 send 方法尚未被調用

2 表明已加載完畢。send 已被調用。請求已經開始

3 表明交互中。服務器正在發送響應

4 表明完成。響應發送完畢

每次 readyState 值的改變,都會觸發 readystatechange 事件。若是把 onreadystatechange 事件處理函數賦給一個函數,那麼每次 readyState 值的改變都會引起該函數的執行。

readyState 值的變化會因瀏覽器的不一樣而有所差別。可是,當請求結束的時候,每一個瀏覽器都會把 readyState 的值統一設爲 4

 

status

服務器發送的每個響應也都帶有首部信息。三位數的狀態碼是服務器發送的響應中最重要的首部信息,而且屬於超文本傳輸協議中的一部分。

經常使用狀態碼及其含義:

404 沒找到頁面(not found)

403 禁止訪問(forbidden)

500 內部服務器出錯(internal service error)

200 一切正常(ok)

304 沒有被修改(not modified)(服務器返回304狀態,表示源文件沒有被修改 )

在 XMLHttpRequest 對象中,服務器發送的狀態碼都保存在 status 屬性裏。經過把這個值和 200 或 304 比較,能夠確保服務器是否已發送了一個成功的響應

 

responseText

XMLHttpRequest 的 responseText 屬性包含了從服務器發送的數據。它是一個HTML,XML或普通文本,這取決於服務器發送的內容。

當 readyState 屬性值變成 4 時, responseText 屬性纔可用,代表 Ajax 請求已經結束。

 

responseXML

若是服務器返回的是 XML, 那麼數據將儲存在 responseXML 屬性中。

只用服務器發送了帶有正確首部信息的數據時, responseXML 屬性纔是可用的。 MIME 類型必須爲 text/xml

 

AJAX開發框架

AJAX實質上也是遵循Request/Server模式,因此這個框架基本的流程是:

對象初始化

發送請求

服務器接收

服務器返回

客戶端接收

修改客戶端頁面內容。

只不過這個過程是異步的。

 

A、初始化XMLHttpRequest對象

function   createXmlHttpRequest(){

var xmlhttp = null;

try{

                   //Firefox, Opera 8.0+, Safari

           xmlhttp=new XMLHttpRequest();

                   }catch(e){//IEIE7.0如下的瀏覽器以ActiveX組件的方式來建立XMLHttpRequest對象

var MSXML =

['MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0',

'MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0',

'MSXML2.XMLHTTP','Microsoft.XMLHTTP'];

  for(var n = 0; n < MSXML.length; n ++){

    try{

      xmlhttp = new ActiveXObject(MSXML[n]);

      break;

    }catch(e){}}

  }

return xmlhttp;

}

 

B、指定響應處理函數

指定當服務器返回信息時客戶端的處理方式。只要將相應的處理函數名稱賦給XMLHttpRequest對象的onreadystatechange屬性就能夠了.好比:

        XMLHttpReq.onreadystatechange = processResponse;

注意:這個函數名稱不加括號,不指定參數。也能夠用Javascript函數直接量方式定義響應函數。好比:

       XMLHttpReq.onreadystatechange = function() { };

// 處理返回信息的函數

function   processResponse() {

 

}

 

C、發出HTTP請求

向服務器發出HTTP請求了。這一步調用XMLHttpRequest對象的open和send方法。

     http_request.open('GET', 'http://www.example.org/some.file', true);

     http_request.send(null)

按照順序,open調用完畢以後要調用send方法。send的參數若是是以Post方式發出的話,能夠是任何想傳給服務器的內容。

注意:若是要傳文件或者Post內容給服務器,必須先調用setRequestHeader方法,修改MIME類別。以下:

http_request.setRequestHeader(「Content-Type」,」application/x-www-form-urlencoded」);

    這時資料則以查詢字符串的形式列出,做爲send的參數,例如:

    name=value&anothername=othervalue&so=on

 

發出Http請求的代碼

//發送請求

function sendRequest(){

//獲取文本框的值

var chatMsg=input.value;

var url="chatServlet.do?charMsg="+chatMsg;

//創建對服務器的調用

XMLHttpReq.open("POST",url,true);

//設置MiME類別,若是用 POST 請求向服務器發送數據,

//須要將"Content-type" 的首部設置爲 "application/x-www-form-urlencoded".

//它會告知服務器正在發送數據,而且數據已經符合URL編碼了。

XMLHttpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

//狀態改變的事件觸發器,客戶端的狀態改變會觸發readystatechange事件,

//onreadystatechange會調用相應的事件處理函數

XMLHttpReq.onreadystatechange=processResponse;

//發送數據

XMLHttpReq.send(null);

}

 

D、處理服務器返回的信息

處理響應處理函數都應該作什麼。

  首先,它要檢查XMLHttpRequest對象的readyState值,判斷請求目前的狀態。參照前文的屬性表能夠知道,readyState值爲4的時候,表明服務器已經傳回全部的信息,能夠開始處理信息並更新頁面內容了。以下:

if (http_request.readyState == 4) {

    // 信息已經返回,能夠開始處理

} else {

    // 信息尚未返回,等待

}

  服務器返回信息後,還須要判斷返回的HTTP狀態碼,肯定返回的頁面沒有錯誤。全部的狀態碼均可以在W3C的官方網站上查到。其中,200表明頁面正常。

if (http_request.status == 200) {

      // 頁面正常,能夠開始處理信息

} else {

    // 頁面有問題

}

 

XMLHttpRequest對成功返回的信息有兩種處理方式:

responseText:將傳回的信息當字符串使用;

responseXML:將傳回的信息當XML文檔使用,能夠用DOM處理。

//處理返回信息的函數

function processResponse(){

   if(XMLHttpReq.readyState==4){ //判斷對象狀態 4表明完成

           if(XMLHttpReq.status==200){ //信息已經成功返回,開始處理信息

                  document.getElementById("chatArea").value=XMLHttpReq.responseText;

          }

   }

      }

 

數據格式摘要

在服務器端 AJAX 是一門與語言無關的技術。在業務邏輯層使用何種服務器端語言均可以。

從服務器端接收數據的時候,那些數據必須以瀏覽器可以理解的格式來發送。服務器端的編程語言通常以以下 3 種格式返回數據:

XML

JSON

HTML

 

XML格式

優勢:

XML 是一種通用的數據格式。

沒必要把數據強加到已定義好的格式中,而是要爲數據自定義合適的標記。

利用 DOM 能夠徹底掌控文檔。

缺點:

若是文檔來自於服務器,就必須得保證文檔含有正確的首部信息。若文檔類型不正確,那麼 responseXML 的值將是空的。

當瀏覽器接收到長的 XML 文件後, DOM 解析可能會很複雜

 

JSON格式

JSON(JavaScript Object  Notation)一種簡單的數據格式,比xml更輕巧。JSON是JavaScript原生格式,這意味着在JavaScript中處理JSON數據不須要任何特殊的API或工具包。

JSON的規則很簡單:對象是一個無序的「‘名稱/值’對」集合。一個對象以「{」(左括號)開始,「}」(右括號)結束。每一個「名稱」後跟一個「:」(冒號);「‘名稱/值’對」之間使用「,」(逗號)分隔。

   規則以下:

       1)映射用冒號(「:」)表示。名稱:值

       2)並列的數據之間用逗號(「,」)分隔。名稱1:值1,名稱2:值2

       3) 映射的集合(對象)用大括號(「{}」)表示。{名稱1:值1,名稱2:值2}

       4) 並列數據的集合(數組)用方括號(「[]」)表示。

         [

           {名稱1:值,名稱2:值2},

           {名稱1:值,名稱2:值2}

         ]

      5  元素值可具備的類型:string, number, object, array, true, false, null

 

JSON 示例

JSON 用冒號(而不是等號)來賦值。每一條賦值語句用逗號分開。整個對象用大括號封裝起來。可用大括號分級嵌套數據。

對象描述中存儲的數據能夠是字符串,數字或者布爾值。對象描述也可存儲函數,那就是對象的方法。

 

解析JSON

JSON 只是一種文本字符串。它被存儲在 responseText 屬性中

爲了讀取存儲在 responseText 屬性中的 JSON 數據,須要根據 JavaScript 的 eval 語句。函數 eval 會把一個字符串看成它的參數。而後這個字符串會被看成 JavaScript 代碼來執行。由於 JSON 的字符串就是由 JavaScript 代碼構成的,因此它自己是可執行的

代碼實例:

處理JSON

例子一:

<script language="JavaScript">

     var people ={"firstName": "Brett", "lastName":"McLaughlin",

                                                        "email": "brett@newInstance.com" };

     alert(people.firstName);

     alert(people.lastName);

     alert(people.email);

</script>

 

例子二:

<script language="JavaScript">

      var people =[

                     {"firstName": "Brett","email": "brett@newInstance.com" },

                     {"firstName": "Mary","email": "mary@newInstance.com" }

                ];

 

    alert(people[0].firstName);

    alert(people[0].email);

    alert(people[1].firstName);

    alert(people[1].email);

</script>

 

例子三:

<script language="JavaScript">

     var people ={

            "programmers":

              [

                {"firstName": "Brett", "email": "brett@newInstance.com" },

                {"firstName": "Jason", "email": "jason@servlets.com" }

              ]

};

 

window.alert(people.programmers[0].firstName);

window.alert(people.programmers[1].email);

</script>

 

例子四:

<script language="JavaScript">

    var people ={

            "programmers": [

            { "firstName": "Brett", "email": "brett@newInstance.com" },

            { "firstName": "Jason",  "email": "jason@servlets.com" },

            { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" }

           ],

          "authors": [

            { "firstName": "Isaac",  "genre": "science fiction" },

            { "firstName": "Tad", "genre": "fantasy" },

            { "firstName": "Frank",  "genre": "christian fiction" }

           ],

          "musicians": [

            { "firstName": "Eric",  "instrument": "guitar" },

            { "firstName": "Sergei", "instrument": "piano" }

           ]};

    window.alert(people.programmers[1].firstName);

    window.alert(people.musicians[1].instrument);

</script>

 

例子五

<script language="JavaScript">

      var people ={

             "username":"mary",

             "age":"20",

             "info":{"tel":"1234566","celltelphone":788666},

             "address":[

                     {"city":"beijing","code":"1000022"},

                     {"city":"shanghai","code":"2210444"}

              ]

        };

 

      window.alert(people.username);

      window.alert(people.info.tel);

      window.alert(people.address[0].city);

</script>

 

JSON 小結

優勢:

做爲一種數據傳輸格式,JSON 與 XML 很類似,可是它更加靈巧。

JSON 不須要從服務器端發送含有特定內容類型的首部信息。

缺點:

語法過於嚴謹

代碼不易讀

eval 函數存在風險

 

解析 HTML

HTML 由一些普通文本組成。若是服務器經過 XMLHttpRequest 發送 HTML, 文本將存儲在 responseText 屬性中。

沒必要從 responseText 屬性中讀取數據。它已是但願的格式,能夠直接將它插入到頁面中。

插入 HTML 代碼最簡單的方法是更新這個元素的 innerHTML 屬性。

 

HTML 小結

優勢:

從服務器端發送的 HTML 代碼在瀏覽器端不須要用 JavaScript 進行解析。

HTML 的可讀性好。

HTML 代碼塊與 innerHTML 屬性搭配,效率高。

缺點:

若須要經過 AJAX 更新一篇文檔的多個部分,HTML 不合適

innerHTML 並不是 DOM 標準。

 

對比小結

若應用程序不須要與其餘應用程序共享數據的時候, 使用 HTML 片斷來返回數據時最簡單的

若是數據須要重用, JSON 文件是個不錯的選擇, 其在性能和文件大小方面有優點

當遠程應用程序未知時, XML 文檔是首選, 由於 XML 是 web 服務領域的 「世界語」

 

案例:省份與城市的聯動下拉列表框

效果演示。

 

聯動下拉:純靜態數據的html方式

實驗步驟:

演示程序運行的效果。

編寫一個靜態province.html頁面,其中使用一個二維數組來裝載全部數據,而後分析和編碼實現省份與城市的聯動下拉列表框。

編寫一個靜態jsonProvince.html頁面,其中使用JSON對象方式來裝載全部數據,而後分析和編碼實現此種數據格式下的省份與城市的聯動下拉列表框。

對於靜態網頁顯示省份和城市,首先要考慮用什麼樣的數據結構來存儲全部信息,每一個選項信息包括名稱和id,若是單獨用一個數組保存各個省份,再用一個數組保存各個省份下的城市,是能夠的,可是須要在兩個地方維護數據,要保持數據的同步。提示:因爲學員基礎的緣故,對於此部分的講解,必定要寫一些示意代碼來進行說明。

與其如此,還不如用一個數組把省份和省份下的城市所有保存起來。

 

沒有惟一和最好的數據存儲結構,只有最適合你和你認爲不錯的數據存儲結構,首先考慮的是把功能實現出來,其次纔是考慮哪一種方式更優雅和方便些。在講課時,對於二維數組和json數據結構,都是先把寫好的靜態province.html頁面中的各個函數刪除掉,而後讓同窗們本身去完成這些函數,這樣同窗們的學習興致很高,確實也能讓同窗們立刻就感到有收穫和有進步。

 

在編寫觸發的顯示某個省份下面的城市的js函數時,先簡單地alert一下選中的省份的值。

 

//下面代碼在firefox下不成功!

//document.getElementById("provinceId").add(optProvince);

//document.getElementById("provinceId").options.remove(i);

 

//下面代碼在firefox下成功!

document.getElementById("provinceId").options.add(optProvince);

document.getElementById("provinceId").remove(i);

 

聯動下拉:動態生成數據的方式

實驗步驟:

編寫一個ListProvinceAction的Action和相應的province.jsp頁面,留出數據待填充,你們清晰看到後面的任務就是生成出數據。

建立表明省份與城市的province和City實體類,而後將相應的實體對象存放在一個單例的MemoryDao中,用一個ArrayList集合存儲全部Province對象,Province對象中保存有一個City對象的集合,在MemoryDao中構建出各個對象及關係。

建立ProvinceService類獲取全部省份列表和CityService類獲取某個省份下的全部城市。

在ListProvinceAction中編寫拼湊出JSP頁面所須要的那個數組字符串。

編寫一個ListJsonProvinceAction的Action和相應的jsonProvince.jsp頁面,以生成使用JSON對象來裝載全部數據,爲了方便拼湊JSON格式的字符串,在各個實體對象中覆蓋toString方法返回自身的JSON格式字符串,這要比在外面最後統一轉換成一個JSON字符串的作法要優雅不少,這種分而治之的思想使得程序健壯且易於維護。

編寫一個ListJsonProvince2Action的Action,快速演示和說明一下如何在其內部用JSONObject與JSONArray工具裏來完成json字符串的生成工做。

使用StringBuilder拼湊字符串時,講解了其與StringBuffer的區別,線程安全比如人走路,若是老是考慮怕與別人或汽車相撞,那走路速度慢,若是不花精力去注意別人,只管埋頭走路,速度確定要快。若是知道是單行通道走,那麼就能夠不去考慮別人,只管本身一我的埋頭走路好了。

 

當要將ArrayList中的元素轉換成js的json格式的字符串輸出時,不須要本身再去拼湊字符串,能夠直接調用ArrayList的toString方法,該方法輸出的字符串正好就符合json數組的語法規範。

 

聯動下拉:用Ajax方式實現的思路分析

傳統方式與Ajax實現方式的對比與選擇:

比如飯館上菜的方式:一種是先讓用戶等較長時間,最後一會兒將全部的菜所有上上來,通常的火鍋店都是這麼作的,還有一種方式就是作好一盤菜就上一盤菜,用戶等待的時間較短,但送餐服務員要跑好屢次,通常的家常菜飯店都是這麼作的。

如何選擇:傳統方式是一會兒把全部數據搞到手,之後只是用js把到手的數據顯示出來便可,第一次獲得數據的時間比較長,若是這個時間長得影響了用戶的感覺,那就考慮用ajax進行改進,不然,能夠直接使用傳統方式。

若是將傳統方式改造爲ajax方式的總結:將原有的一個jsp頁面改成兩個jsp頁面來實現,第一個頁面爲那些固定不變的內容和javascript代碼,第二個頁面爲那些要改變的區域的代碼,所以原來用一個action或servlet實現的代碼要改變爲用兩個action或servlet來實現,這稱爲二步視圖法。

實現的思路剖析:

第一次要得到一個頁面,瀏覽器之後一直顯示這個頁面,之後的每一個操做都觸發這個頁面內部的一個javascript函數,再由這個javascript函數去發請求和處理迴應結果。

第一次得到的頁面應該包含什麼信息?頁面的初始內容和javascript函數。

之後的每次請求要得到什麼樣的結果?

若是本應用只顯示幾個省份及各個省份下面的少數幾個城市,則能夠用傳統方式。若是本應用是要顯示出全國全部省份下面的全部城市,涉及的數據量就比較大了,若是要從數據庫中一會兒查出31個省和它們下面的全部城市,一般要涉及32條sql語句,花費的時間較長;若是改成Ajax按需取數據的方式,即選擇哪一個省份後,再去取該省份下的城市,這樣,第一次展示的速度就較快。給你們看看騰訊的網吧充值界面圖。

 

聯動下拉:用json數據傳輸格式的Ajax方式實現

步驟:

編寫AjaxListProvince的Action和ajaxProvince.jsp頁面,在一個下拉列表框中列出全部省份,編寫觸發和發送獲取某個省份下面的城市的請求消息的代碼,先簡單的alert一下響應結果。

根據客戶端的請求信息,分析和編寫一個ListCities的Action調用CityService類獲取某個省份下的全部城市,Action返回一個包含有某個省份下的全部City的json格式的數組。

在ajaxProvince.jsp頁面中編寫處理返回結果的javascript代碼,使用javascript本身的eval方法處理json字符串。

改進爲用prototype本身的json支持來處理返回的json串,包括擴展的String.evalJSON()方法和transport.responseJSON屬性這兩種方式。

因爲本例子程序返回的城市對象很簡單,可使用一個map來表示某個省份下的全部City信息,同時簡化客戶端的javascript代碼。

編寫jsp頁面,由於沒有涉及<html:form>表單,因此沒法使用struts的html:optionCollections標籤來生成下拉列表框的option選項,只能使用jstl標籤。

 

注意:改成ajax方式來實現時,傳遞給事件處理函數中的參數再也不是選擇項的索引號,而是選擇項的值了,由於每次都要從服務器端來獲取某個省份下的城市集合,傳給服務器的參數是省份的id值。

瀏覽器一上來要發兩次請求,第一次獲得省份,第二次獲得當前選中的省份的城市信息,而不是一次就獲得省份和第一個省份的城市信息,一個模塊專門負責省份,不要讓它既處理省份,又處理城市。

 

學員在作第二步時,作好ListCityAction後,先用瀏覽器測試一下,而後用ajax調用,在ajax調用的回調函數中,先alert一下返回的這個串,最後再把這個串轉換成爲json對象。

在baidu中搜素」jquery select 添加選項」

學員寫的一段代碼:

for(var i=0;i<data.length;i++){

               var op=$("<option>").attr('id',data[i][1]).html(data[i][0]);   

               $("#provinceId").append(op);

            }

 

分別用jquery和protoye作一遍。Jquery的json支持作一遍。Onchange事件用prototype和jquery提供的方式來註冊。對於清楚下拉列表框中的全部選項,可使用jquery對象的empty函數或者讓其innerHTML爲空。用jquery時,最好是把事件處理的註冊代碼放在js中寫,而不是放在html中,所謂的內容與行爲相分離,術語借鑑了內容與表現相分離的說法。

有學員提到了如何本身實現緩存,藉此機會正好把緩存給實現了一下:

能夠用數組方式實現,用其id值做爲數組元素的索引,若是id=99,測試數組的長度一下就變成了100,全部這樣不合理,代碼以下:

var data=[];

data[pid] = cities;

alert(data.length);

因而想到改成用對象方式來實現:

var data={};

data[pid] = cities;

for(var a in data)

{

alert(a + 「:」 + data[a]);

}

後來用數組進行循環,發現實際上也只有添加進去的幾個元素,這裏數組與對象的區別彷佛就是對象沒有length屬性。

 

有問題:$("#provinceId").change(fillCity($(this).val()));

正確: $("#provinceId").change(function(){

         fillCity($(this).val());

});

 

用jquery.each方法迭代出來元素是htmlelement類型,而不是jquery對象。可使用nodeName來查看htmlelement元素名。

 

聯動下拉:用xml數據傳輸格式的Ajax方式實現

步驟:

編寫一個ListCity2的Action,返回一個包含有某個省份下的全部City的xml文檔。

直接用瀏覽器訪問ListCity2,測試查看返回的xml文檔內容是否正確。

客戶端頁面改成ajaxProvince2.jsp,在其中編寫解析xml文檔內容和將結果顯示在下拉列表框中的代碼,而且將AjaxListProvince配置爲/ AjaxListProvince2.do

今天用jquery作時,只要在發送請求時,將dataType:’xml’,那麼,jquery就回將xml文檔轉換成Document對象,並將該Document對象做爲參數傳遞給回調函數,也就是說,此時的回調函數接收的參數就是Document對象。

/*拼出以下的數據格式,該如何作呢?

*

<cities>

<city>

<id></id>

<name></name>

</city>

<city>

<id></id>

<name></name>

</city>

</cities>

*/

 

Jsp就是拼湊大段字符串的技術,是模板技術,大量固定不變的串中偶爾要夾雜一點變化的數據,這就是jsp的用武之地。

jsp就是爲了方便拼湊大量文本串而推出的技術,咱們爲什麼放着這麼好的東西不用呢?

不須要寫AjaxListProvince2Action,只須要把AjaxListProvinceAction再配置一遍,這正是mvc的優勢,控制器和模型不變,可輕鬆改變視圖(view)

 

聯動下拉:返回整個下拉列表框的HTML代碼

步驟:

編寫一個ListCity3的Action,返回一個包含有某個省份下的全部City的下拉列表框的html代碼。

直接用瀏覽器訪問ListCity3,測試查看返回的html代碼是否正確。

客戶端頁面改成AjaxProvince3.jsp 和在其中定義一個<div>元素來容納服務器返回的下拉列表框,而且將AjaxListProvince配置爲/ AjaxListProvince3.do。

爲何有了前面兩種很是優雅的作法,還要講那些不優雅和很土的作法呢?由於外面有些公司用的就是土方法,真正用優雅方式的是很牛的好公司,這樣的好公司並很少,外面的公司爲何要用土方法呢?比如你讀了小學一年級就能夠掙錢了,之後一直忙於掙錢,就不必去讀博士了,因此一直會用小學一年級的方式工做下去。雖然你讀博士後,掌握了只有博士能掙到的錢的本領,掙錢的方式可能更優雅,但有時候,博士也要用小學一年級的方式去掙錢,例如,有的博士是房產公司的經理,但他掙錢的方式很原始,徹底是小學一年級水平的方式,只要會送禮和會喝酒就能夠,讀博士掌握的本領全用不上也是可能的。

 

你們對有的Action用response.getWriter()方法直接輸出結果,對有的Action卻跳轉到一個jsp頁面上的關係與區別老是搞不太清楚,問這問題的人都是屬於基礎比較不錯,已經開動了腦筋的學員。看來你們對jsp的根本做用和工做原理了解得仍是不夠好。

 

返回的html代碼片斷前面有幾個空格和換行,致使顯示的城市下拉列表框與省份下來列表框之間有很大的空襲,我是讓返回的html代碼前時儘可能去掉前面的空格,這時候應該用prototype或jquery提供的去掉兩端空格的方法來完成。

 

聯動下拉:返回向下拉列表框填充選項的js代碼

步驟:

編寫一個ListCity4的Action,返回一個用於將某個省份下的全部City添加進下拉列表框的javascript代碼。

直接用瀏覽器訪問ListCity4,測試查看返回的javascript代碼是否正確。

客戶端頁面改成AjaxProvince4.jsp 和使用eval方法執行服務器端返回的javascript代碼,而且將AjaxListProvince配置爲/ AjaxListProvince4.do。

這種方式既不優雅,也不簡單,但有人用,我以爲徹底是無用,毫無價值。

今天用jquery作時,首先用eval(「(「 + msg + 「)」)執行時,ie老是報告錯誤,說缺乏),換成firefox查看,提示錯誤以下:

missing ) in parenthetical

  document.getElementById('cityId').options.add(new Option('武漢',3));\n

原來是在返回的字符串最後多了個\n,把整個串用()括起來後,就至關於一個完整的字符串中間換行鍘成兩段,這種語法是不行的。

因而,去掉(),即代碼改成eval(msg),再運行,結果就正常了。

最後讀jquery的Ajax函數的文檔,發現dataType選項有一個設置值爲script,因而設置了這個選項,發現city的填充效果被double,

這說明將dataType設置爲script後,jquery會自動幫咱們執行javascript代碼,在這種狀況下,不寫success回調函數也能夠看到運行效果。

-------------------------------------------------------------------------------------------

最後要給你們總結一下,這樣你們思路就不混亂了:對於用4種不一樣方式返回城市,第一步顯示省份的頁面須要作幾個?返回省份信息的前置Action須要寫幾個。

對於第二步返回城市信息,除了json以外的3種方式須要作幾個頁面?須要作幾個返回城市信息的Action?爲何返回json數據時的Action與返回其餘數據時的Action不一樣?

 

案例擴展:多級地區的動態展示

實驗步驟:

演示和分析程序運行的效果。(每選擇一個區域,則顯示一個包含有其全部子區域的下拉列表框,並清除其餘不相關的下拉列表框;當選擇了某個沒有子區域的選項後,再也不顯示出新的下拉列表框,而是顯示該區域的網吧)

分析數據庫表結構該如何設計,並執行預備的腳本文件建立表結構和數據。

分析JSP頁面該如何設計:

第一個返回的頁面應該包含哪些內容?

之後每次請求得到的結果是什麼?返回的結果怎樣展示在返回的第一個頁面中?動態生成出下拉列表框和將下拉列表框追加到其餘列表框後面,或者提早預約義若干span元素,將新增的下拉列表框添加到相應的span元素中。若是要實現用表格來顯示某個區域的網吧,服務器端返回的要麼是select元素,要麼是table元素,客戶端要判斷結果的類型。

編碼實現:先用span的方式實現;再用prototype的刪除和添加功能。

 

我是一個通用的產品,要賣給不一樣的公司,不一樣公司的級別分類的層次是不同,咱們一般應該容許無限極分類,還有書的分類,這樣的系統的數據庫該如何設計。是設計無限個表,仍是設計一個表。無限級分類應用不少,例如論壇的版面,帖子的回覆等等。

 

id,name,parentid

1,  集團,0 

2.  一公司, 1

3. 二公司, 1

4.三公司,1,3  

 

查詢集團下的直接子部門:select * from dept where parentid=0;

  查詢一公司下的直接子部門:select * from dept where parentid=1;

爲一公司添加子部門:insert into detp values(..,1)

  父親能夠知道本身的全部孩子,孩子能夠知道本身的父親,這就很知足需求了嘛!

 

網吧爲何要有一個字段指向所屬的區別?由於要列出一個區域下的全部網吧,若是沒這需求,固然也就不須要那個字段了。

 

這裏的第一步不須要顯示出全部省份,由於顯示省份的方式和顯示子地區的方式徹底同樣,因此,顯示省份信息藉助第二部操做來完成,只是第一步作完後當即進入第二步弄出省份。

 

先不作網吧部分,等作完地區後,讓學員看看使用dao查詢網吧只是複製工做,環境搭建只是一次性的工做,只要環境搭建好了,開發過程就是這樣的拷貝和複製。

對於採用span元素的實現方式,每一個下拉列表框都要用同一個函數來實現,這個函數須要接受兩個參數:要顯示的地區的父級id(即列表框要顯示哪一個id地區下的子地區),獲得顯示的結果放在哪一個span元素裏。先徹底用手工編寫方式分析服務器每次返回的下拉列表框的html代碼怎樣?再分析用jsp如何生成,因爲返回的結果既要有某個id的子地區,又要在生成的下拉列表框的onchange事件中指定下一級地區列表框所放置的span元素,因此,傳遞給服務器的參數也要有兩個。若是不給服務器傳遞當前span元素的id值,而是等服務器返回一個結果後,而後客戶端再用js代碼來指定下一個span元素的id值,這樣更好,由於服務器端不用考慮客戶端的頁面狀況了,即服務器端的代碼不用隨客戶端頁面的改動(地區級別)而改變,這中方式能夠留給同窗們本身作。對於這種狀況,js代碼中還要判斷服務器返回的是<select>仍是<table>,是table則往網吧的<span>中填寫。

每次添加新的下拉列表框前,都是刪除原來的當前要生成的下拉列表框之後的全部列表框和表格,再更新當前要生成的下拉列表框。這裏操做的參數是指當前要生成的下拉列表框所在的span元素的id。

 

對於採用prototype的添加和刪除功能,獲得全部弟弟並刪除,增長新弟弟。有一點奇怪的是,使用$(sibling).remove方法,沒法完成刪除功能,但使用Element.remove(sibling)卻能夠,其中具體的差異在哪,尚未找出來。另外每次生成一個下拉列表框,而後再刪除,再添加,下次生成的下拉列表框與上次生成的下拉列表框有必定的距離,這就是由於返回的<select>標籤前面有空格致使的。也能夠利用Prototype提供了Element.cleanWhiteSpace方法來清除全部空格。

 

每次添加新的下拉列表框前,若是不是第一個(經過調用函數時,有無傳遞當前元素這個參數來判斷),則刪除當前發生事件的下拉列表框之後的弟弟(包括全部後續列表框和表格),再新增一個下拉列表框,若是是第一個,則直接新加。這裏的參數是當前正在發生事件的下拉列表框。

 

設計多級分類,可使用字符串類型的id,用id的值來表示級別和隸屬關係,例如,001,001001,001002,001001001等。這是咱們十年前老是樂意當着一個經驗向你們講解的知識,如今因爲掌握的新技術太多了,都忘記講這些之前的經驗了,多是人都有點喜新厭舊的習慣吧。其實,對於新手來講,咱們這些老多年前的經驗仍然是頗有價值的。

 

一道面試題:把span1變成span2,把span2變成span3,把span3變成span4,把span5變成span6

相關文章
相關標籤/搜索