aspx頁面javascript的幾個trick

來源:互聯網
上載者:User
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);
              }
            }
          }
        }
      }
    }
  }
}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.