zoukankan      html  css  js  c++  java
  • asp.net ID,ClientID和UniqueID

    在ASP.NET 的服务器端控件中有三种关于 ID 的属性,ID, ClientID 和 UniqueID。
    ID 表示控件的服务器端编程的标识符,我们写"服务器端的代码",就要用到这个 ID, 通过这个 ID 可以在服务器端对服务器端控件的属性、方法和时间进行编程访问。(可写)
    ClientID 表示由服务器端生成的客户端控件的ID,"经常用于在客户端脚本中访问服务器控件所呈现的 HTML 元素"。一般情况下与服务器端的 ID 相同,有时,不能为控件生成唯一的名称,例如,如果Repeater 空间在它的某个模板中包含一个 Label 控件,则将在客户端生成多个该 Lable 的 HTML 元素, 为防止命名冲突,ASP.NET 为各个服务器控件生成一个唯一的 ClientID ,ClientID 通过将子控件的父控件的 UniqueID 值与控件的 ID 值连接生成,各个部分之间以下划线 _ 连接。(只读)
    UniqueID 用于获取服务器控件的唯一的、以分层方式表示的标识符。当将控件放置到重复控件(Repeater、DataList和DataGrid)中时,将可能生成多个服务器端的控件,这就需要区分服务器端的各个控件,以使它们的 ID 属性不冲突。UniqueID 通过将子控件的父控件的 UniqueID 值与控件的 ID 值连接生成,各个部分之间以IdSeparator 属性指定的字符连接。默认情况下, IdSeparator 属性为冒号字符 (:)。此属性为在 .Net Framework2.0种新增加。js与aps.net交互一般情况下使用<%=控件ID.ClientID%>就OK了,但如果用到母版页(MasterPage)则要使用UniqueID获得获值。(只读)


    例如,创建以下 ASP.NET 服务器控件:
    <asp:textbox id="TextBox1" runat="server" text="Sample Text" />
    ClientID 属性被设置为 TextBox1,在基于 HTML 的浏览器中,其结果元素与以下所示类似:
    <input name="TextBox1" type="text" value="Sample Text" id="Text1" />

    可以使用这些属性在客户端脚本中引用服务器控件。通常,必须在客户端脚本中用完全限定引用来引用控件;如果控件是页面中 form 元素的子控件,则一般使用document.forms[0].TextBox1.value = "New value"在客户端脚本中引用控件。
    有些控件将子控件呈现在页面中。这些控件中包括数据列表控件(如GridView、DetailsView、FormView、DataList 和 Repeater 控件)、用户控件和 Web 部件控件。可以看到,在这些情况下,子控件可能不具有唯一的 ID, 这可能是因为子控件是在某个模板中定义的,该模板会为每个数据行(数据列表控件)生成新的控件实例,也可能是因为可以从外部源(用户控件和 Web 部件控件)将父控件添加到页面中对于每个子控件:控件的 UniqueID 被呈现为 name。控件的 ClientID 被呈现为 id 属性。
    ClientID 和 UniqueID 属性都基于原始的 ID 属性,并用足够的信息进行了修改,以保证页面中结果的唯一性。ClientID的值可在客户端脚本中引用。如果在浏览器中显示一个具有命名容器的页面,则可以查看该页面的源文件,从中找到唯一的 ID,这些 ID 作为命名容器子控件的 name 属性和 id 属性生成。但是,建议不要依赖于直接引用在浏览器中看到的 ID。因为用于生成子控件唯一ID 的公式可能会发生变化,应当获取子控件的 ClientID 属性值,并用该值来引用该子控件。例如,您可能会在页面中动态创建客户端脚本。如果客户端脚本引用一个子控件,则应获取该子控件的 ClientID 属性,并将其嵌入到动态脚本中。
    例2:

    假设有子控件:
    <asp:TextBox ID = "textboxInfo" runat ="server" Text = "Test Text box" name="haha"></asp:TextBox>
    那么我们可以在脚本中这样写
    var tempt = '<%=textboxInfo.ClientID%>';
    var controlname = document.getElementById(tempt).name;
    var controlid = document.getElementById(tempt).id;
      还有一个问题我们需要注意:在使用UniqueID和ClientID的时候要小心点,千万不要“迫不及待”地使用了这些属性,在运行的过程中可能会碰到一些让人头疼的问题.


    注意
    除了用来分隔 ID 值的是下划线字符而不是 IdSeparator 属性指定的字符以外,为控件生成的 ClientID 值与 UniqueID 值相同。默认情况下,IdSeparator 属性设置为冒号字符 (:)。由于 ClientID 值不包含冒号字符,因此,它可以用于不支持包含冒号的 ID 的 ECMAScript。ClientID 值经常用于以编程方式访问为客户端脚本中的控件呈现的 HTML 元素。有关详细信息,请参见 ASP.NET 网页中的客户端脚本。
    总结:
    ID,用于server端编程引用控件,没有对应的client值,即不呈现到html中。
    UniqueID,
    asp.net引擎按控件树层次生成的分层形式限定的标志符,连接符默认为 $ (美元符号)【注:MSDN说默认为 : (冒号),实际是 $ ,可能文档有误吧】,此连接符在asp.net 2.0 中由属性 IdSeparator 指定,在client中呈现为html元素的name属性
    此属性主要用来提交(PostBack)客户端数据,如Request.Form[someControl.UnqiueID]
    ClientID,
    由父控件的UnqiueID连接本身ID而成,但是连接符不一样,默认为   _ (下划线),此连接符在asp.net 2.0 中由属性 ClientIDSeparator 指定,在client中呈现为html元素的id属性,此属性主要在客户端教本中使用,如 var o = document.getElementById('<% = someControl.ClientID %>');
    关于 UniqueID的层次分隔符号,1.x 中为 :(冒号),而 2.0 已实现为 $(美元符),主要原因可能是 javascript 中标识符是允许 $,而不允许 : 的。(当你偷懒的时候,可以在 js 中直接使用表单元素的 name属性应用该表单元素,而不用 document.getElementsByName 或者 document.getElementById,不推荐:)

    ASP.NET 使用的回发机制(简单版本)是通过一个原型为 __doPostBack(<ControlUniqueID>, <CommandArgs>) 的 javascript 函数
    function __doPostBack(eventTarget, eventArgument) {
        if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
             theForm.__EVENTTARGET.value = eventTarget;
             theForm.__EVENTARGUMENT.value = eventArgument;
             theForm.submit();
         }
    }
    此函数的第一个参数 <ControlUniqueID> 对应引起页面回发控件的客户端 name 属性/服务端 UniqueID 属性,当用户引发一个事件,如点击按钮,选择列表框的某一项,首先通过 _doPostBack 函数将此值存在隐藏域中,然后提交页面。
    在服务器端,ASP.NET 引擎通过 HttpRequest.HttpMethod 确定请求是否为 post 方式,若是,则检索HttpRequest.Request.Form["__EVENTTARGET'], 获取引发回发的控件唯一标识符,并在页面控件集合层次中查找,若找到此控件,则将在适当阶段引发服务器端事件。
    另补充控件变化规律如下:
    控件名字发生变化是因为 INamingContainer这个接口。这个接口没有任何方法,仅只作为一个标记。ASP.NET维护控件name和id生成的规律是:NamingContainer爷爷$NamingContainer爸爸$该控件的IDid则一般将$换为"_"。
    你把控件直接放到form下,它头顶唯一一个NamingContainer是Page,但是这个是特殊的逻辑,不会生成__Page_控件名,所以就只剩控件名了,于是ID看起来没有变化。
    当你把控件放到Repeater中时,Repeater自己被INamingContainer标记,同时,每一次循环,它会把模板内的控件重新生成一 遍,同时生成一个RepeaterItem, 把这些根据模板生成的控件加入RepeaterItem的子控件。这个RepeaterItem也是一个NamingContainer. 于是控件中就会带有:
    RepeaterID(Data)_RepeaterItemID(ctl + 号码)_控件ID.
    不过非runat=server控件因为不由ASP.NET维护, 不会发生变化. UserControl.ascx由于其基类也是一个NamingContainer, 所以如果你把控件放入.ascx, 然后在页面上引用, 则前面又会多一层UserControl的ID.
    通过controls集合访问服务器控件:
    在VS2005中新建一个.aspx文件,打开HTML页会发现一个原先的声明从
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    变成了
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">!
    很早以前就称的HTML的接班人XHTML,现在MS终于要将它扶正了..
    这样在写HTML代码时就要注意了,
    如:
    <font>
        <div>
        </font>
        </div>
    是无法在Vs2005中的Design模式中正确显示的[很明显的错误,但在HTML可以正常显示].. ,XHTML的语法比HTML严格的
  • 相关阅读:
    50.Ext_数字输入框_Ext.form.NumberField
    49.Ext.form.TextField()基本用法
    48.EXt.Data.JsonReader()
    47. Ext.form.Field.prototype.msgTarget
    46. Ext中namespace的作用(转)
    45. ExtJS ComboBox 下拉列表详细用法
    44. Ext信息提示对话框
    43. ExtJs控件属性配置详细
    42.extjs Combobox动态加载数据问题,mode:local 还是remote
    堆叠顺序
  • 原文地址:https://www.cnblogs.com/longyi/p/2618684.html
Copyright © 2011-2022 走看看