分享:aspx頁面&#106avascript的幾個trick
2024-05-04 11:06:23
供稿:網友
1、一般而言,如果想給aspx頁面上的web form control加上一些javascript的特性,可以用attributes.add來實現。
例如,對textbox txt,可以:
txt.attributes.add("onclick", "fcn0();");
那么,在web頁面上click它的時候,就會調用fcn0這個javascript函數。
1.1、例外的情況是,對于ide無法辨認的屬性的解析。
比如對一個radiobutton rbt,ide不能辨認onclick這個屬性,那么,類似上面的語句,
rbt.attributes.add("onclick", "fcn1(this);");
在.net framework 1.1中,將解析成
<input type=radio id=rbt >...
而在在.net framework 1.0中,將解析成
<span ><input type=radio id=rbt>...</span>
注意到,fcn1中,參數this對應的對象就不同了。這是一個細微的差別。
2、而對于html control,需要多做一點事情。
在設計aspx頁面的時候,從工具欄拖一個web form control,比如說,textbox到頁面,會發生兩件事:
一、aspx頁面多一句
<asp:textbox id="textbox1" runat="server" width="102px" height="25px"></asp:textbox>
二、code behind多一句
protected system.web.ui.webcontrols.textbox textbox1;
如果是html control,那么,第一句中,runat="server"不會出現,而第二局不會被自動添加。
因此,如果要訪問html control,需要
一、aspx頁面的語句中添加runat="server"屬性,成為
<input type="text" size="9" id="htxt" runat="server">
二、code behind中顯示的聲明
protected system.web.ui.htmlcontrols.htmlinputtext htxt;
注意到第一句的id和第二句的變量名是相同的。
2.1、注意到,前面system.web.ui.webcontrols.textbox對應的html control是system.web.ui.htmlcontrols.htmlinputtext,對應的html的tag是<input type="text">,
相應的,html的tag <body>對應的html control是
public system.web.ui.htmlcontrols.htmlgenericcontrol mybody;
2.2、有一點例外的是html的<form> tag對應的onsubmit的事件??催@樣一個aspx頁面
<%@ page language="c#" codebehind="webform2.aspx.cs" autoeventwireup="false" inherits="testcs.webform2" %>
<!doctype html public "-//w3c//dtd html 4.0 transitional//en" >
<html>
<head>
<title>webform2</title>
<meta name="generator" content="microsoft visual studio 7.0">
<meta name="code_language" content="c#">
<meta name="vs_defaultclientscript" content="javascript">
<meta name="vs_targetschema" content="http://schemas.microsoft.com/intellisense/ie5">
<script language="javascript">
function fcn1()
{
prompt("hi", "fcn1");
}
</script>
</head>
<body ms_positioning="gridlayout">
<form id="webform2" method="post" runat="server" onsubmit="fcn1();">
<asp:button id="button1" runat="server" width="86px" height="29px" text="button"></asp:button>
<asp:dropdownlist id="dropdownlist1" runat="server" width="188px" height="17px" autopostback="true">
<asp:listitem value="a">a</asp:listitem>
<asp:listitem value="b">b</asp:listitem>
<asp:listitem value="c">c</asp:listitem>
</asp:dropdownlist>
</form>
</body>
</html>
內容很簡單,定義了一個javascript函數fcn1,放了一個button button1和一個autopostback的dropdownlist dropdownlist1,運行它,可以看到:點擊button1,會先執行fcn1然后postback,而選擇dropdownlist1的不同選項,將只會postback,而不會觸發fcn1。
微軟autopostback=true的webcontrol實現postback,原理是這樣的:
一、如果此aspx頁面有autopostback=true的webcontrol,那么會寫下面一段javascript語句定義一個叫__dopostback的javascript函數。
<script language="javascript">
<!--
function __dopostback(eventtarget, eventargument) {
var theform;
if (window.navigator.appname.tolowercase().indexof("netscape") > -1) {
theform = document.forms["webform2"];
}
else {
theform = document.webform2;
}
theform.__eventtarget.value = eventtarget.split("$").join(":");
theform.__eventargument.value = eventargument;
theform.submit();
}
// -->
</script>
二、例如是上面的dropdownlist,將會render成:
<select name="dropdownlist1" onchange="__dopostback('dropdownlist1','')" language="javascript" id="dropdownlist1" >
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
</select>
這樣,通過javscript調用theform.submit();來submit form,postback,但是,theform.submit將不會觸發form的onsubmit事件!
這是微軟的一個bug。
解決的方法可以看這里:http://www.devhawk.net/art_submitfirefixup.ashx,這里提供了一個dll及源代碼,使用的時候,在project的reference里加入這個dll,然后在web.config中加上一段
<httpmodules>
<add type="devhawk.web.submitfirefixupmodule,submitfirefixupmodule" name="submitfirefixupmodule" />
</httpmodules>
就可以了。
3、一個應用。
常常聽到抱怨,說如果在browser端用javascript改動了某個<select>元素,那么,它對應的server端的dropdownlist不能得知這個更新。
這種情況可能出現在“級聯”的dropdownlist中,比如第一個dropdownlist是省份,第二個是城市;也可能出現在,從第一個dropdownlist選擇某些項加入到第二個dropdownlist中。
對此使用以上的技術,我做了一個這樣的解決方案(類似于viewstate的方法):
一、我定義了一個長寬都是0的textbox txtwrap,并把所有我想處理的dropdownlist都加上athososw="true" 這樣的屬性,準備處理。
二、參照上面2.2的內容,我加入了submitfirefixupmodule,來保證觸發form的onsubmit事件。
三、form的onsubmit事件將執行javascript函數fcnathosonsubmitwrap,它將遍歷athososw屬性為true的dropdownlist,記下數據,最后合并起來放到txtwrap里,其實這就是一個序列化的過程。代碼如下:
function fcnathosonsubmitwrap()
{
txtwrap = document.all["txtwrap"];
var i;
var strwrap = '';
for(i=0;i<document.all.length;i++)
{
ctrl = document.all[i];
if(ctrl.tagname.touppercase() == 'select' && typeof(ctrl.athososw) != 'undefined' )
{
if(ctrl.athososw.touppercase() == 'true')
{
strwrap += fcnathoswrapselect(ctrl) + '&&&';
}
}
}
if(strwrap.length>3)
txtwrap.value = strwrap.substring(0, strwrap.length-3);
};
//athososw
function fcnathoswrapselect(ctrlselect)
{
var i;
var strwrapselect = ctrlselect.id + '&' + ctrlselect.tagname;
var strvalue='';
var strtext='';
for(i=0; i<ctrlselect.options.length; i++)
{
strvalue = ctrlselect.options[i].value;
strtext = ctrlselect.options[i].text;
strwrapselect += '&&' + i + '&' + strvalue.replace(/&/g, '%26') + '&' + strtext.replace(/&/g, '%26');
};
return strwrapselect;
};
四、form的page_load中調用clscommon.unwrapcontrol(this, txtwrap.text);來反序列化。clscommon是我的工具類,unwrapcontrol方法代碼如下:
static public void unwrapcontrol(system.web.ui.page pgunwrap, string strunwrap)
{
regex r3 = new regex("(&&&)"); // split on hyphens.
regex r2 = new regex("(&&)"); // split on hyphens.
regex r1 = new regex("(&)"); // split on hyphens.
string[] sa3, sa2, sa1;
string s3, s2, s1;
int i3, i2, i1;
string strid, strtagname;
system.web.ui.control ctrlunwrap;
dropdownlist ddlunwrap;
listitem liadd;
s3 = strunwrap;
sa3 = r3.split(s3);
for(i3=0;i3<(sa3.length+1)/2;i3++)
{
s2 = sa3[i3*2];
if(s2.length>0)
{
sa2 = r2.split(s2);
if(sa2.length>1)
{
s1 = sa2[0];
sa1 = r1.split(s1);
if(sa1.length==3)
{
strid = sa1[0];
strtagname = sa1[2];
ctrlunwrap = pgunwrap.findcontrol(strid);
if(ctrlunwrap !=null)
{
if(strtagname == "select")
{
ddlunwrap = (dropdownlist)ctrlunwrap;
ddlunwrap.items.clear();
for(i2=1; i2 < (sa2.length+1)/2;i2++)
{
s1 = sa2[i2*2];
sa1 = r1.split(s1);
liadd = new system.web.ui.webcontrols.listitem(sa1[4],sa1[2]);
ddlunwrap.items.add(liadd);
}
}
}
}
}
}
}
}
athossmth版權所有,轉載請注明。