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 onclick="fcn1(this);">... 而在在.net framework 1.0中,将解析成 <span onclick="fcn1(this);"><input type=radio id=rbt>...</span> 注意到,fcn1中,参数this对应的对象就不同了。这是一个细微的差别。 2、而对于HTML control,需要多做一点事情。 在设计aspx页面的时候,从工具栏拖一个web form control,比如说,TextBox到页面,会发生两件事: 一、aspx页面多一句 <asp:TextBox id="TextBox1" style="..." 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 style="..." 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" style="Z-INDEX: 103; LEFT: 423px; POSITION: absolute; TOP: 83px" runat="server" Width="86px" Height="29px" Text="Button"></asp:Button> <asp:DropDownList id="DropDownList1" style="Z-INDEX: 104; LEFT: 284px; POSITION: absolute; TOP: 163px" 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" style="..."> <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版权所有,转载请注明。

|