技巧一:在用戶端的javascript指令碼中擷取伺服器端控制項的值
以前,當我們需要在指令碼裡訪問頁面內一個對象的時候,一般都是通過對象的id或name。就像這樣——
// ...
function getText()
{
return document.form1.Text1.value; // Text1就是對象的id
}
// ...
現在,ASP.NET讓我們越來越習慣使用TextBox作為使用者輸入的途徑。如果我們想在用戶端指令碼裡訪問一個TextBox,原先的做法就行不通了——
// ...
function getText()
{
return document.form1.Text1.value; // Text1還是對象的id?
}
// ...
瀏覽頁面時,會有一個指令碼錯誤——“Text1對象不存在”。原因就在於,Text1作為伺服器端控制項TextBox,在被發送到用戶端之前,先由.NET Framework進行轉換,而它的id顯然也是轉換的一部分。如果你在用戶端查看頁面的原始碼,你可以發現原先的Text1已經不存在,取而代之的是一個普通的INPUT——
這就是轉換的結果,id不再是設計時所指定的id。如果我們要在用戶端訪問這個文本輸入框,也必須改變訪問的id。如何改變?直接將
document.form1.Text1
改為
document.form1.item("Test_Text1") // 保險起見,使用item由id或name得到控制項
或者
document.getElementByID("Test_Text1") // 保險起見,使用getElementByID由id或name得到控制項
可以嗎?當然可以!只要你的控制項id固定是"Text1"。
但是,只有這個條件還不夠。"Test"又是什嗎?它也應該被考慮在內(幸好form的id不會改變,否則要關心的內容又會多一個)。
你或許已經看出,Test就是這個Web頁面的名字。對嗎?——不完全對:P
確切地說,控制項轉換後id中的"Test"是其所在的Web表單對象的ClientID。所有的ASP.NET對象都在伺服器端有一個執行個體(如果你物件導向的基礎不夠,建議也補完一次吧),而這個"Test",就是這個頁面執行個體對象的ClientID。而ClientID,則是每個Web表單頁的一個屬性,它指明了這個Web表單在用戶端的標識。
為什麼要這麼複雜?道理很簡單,我們並不能在用戶端指令碼裡確定頁面的ClientID和控制項的ID。
那應該怎樣做呢?
“在伺服器端代碼裡產生用戶端javascript。”——似乎非常複雜,其實並不困難,只要在伺服器端Page_Load事件裡加上(在IsPostBack判斷之外)——
RegisterStartupScript("start",
"\n \n");
RegisterStartupScript是Web表單(System.Web.UI.Page類)的一個方法,作用是在產生的頁面裡註冊用戶端指令碼。
在這裡,我們添加了一個getText()函數,作用和之前的getText()一樣,所不同的在於,它所訪問的控制項id並非指令碼內指定,而是在伺服器端根據頁面的ClientID(this.ClientID,this就是頁面自己)和Text1控制項的ID(this.Text1.ID)動態產生的。
編譯之後重新瀏覽,我們會在新的頁面原始碼裡找到這個由伺服器端代碼產生的javascript函數。此時,在頁面的其他地方調用getText()函數就將正確得到Text1中的內容了。