如何阻止 ASP.NET 更改 ID 以使用 jQuery

Posted

技术标签:

【中文标题】如何阻止 ASP.NET 更改 ID 以使用 jQuery【英文标题】:How to stop ASP.NET from changing IDs in order to use jQuery 【发布时间】:2010-10-04 14:39:58 【问题描述】:

我的网页中有这个标签控件

<asp:Label ID="Label1" runat="server" Text="test"></asp:Label>

当页面呈现时,控件的 id 会变成这样的东西

  <span id="ctl00_ContentPlaceHolder1_Label3">test</span>

如何阻止 asp.net 更改 ID 以执行这样的 jQuery 操作

$('#label1').html(xml);

【问题讨论】:

其他答案已经显示了各种解决方法,因为 ASP.Net 令人讨厌地坚持创建自己的客户端 ID。尽管它对您当前的问题没有帮助,但我最近读到这将成为今年晚些时候 ASP.Net 4.0 中的功能之一。想你可能会感兴趣。 仅供参考,这是在 ASP.NET 4.0 中出现的(控制服务器控件的客户端 ID 的能力) 【参考方案1】:

简答:

设置ClientIDMode="Static"

<asp:Label ID="myLabel" ClientIDMode="Static" runat="server" Text="testing"></asp:Label>

长答案:

.NET 4 现在可以让您选择您的ClientIDMode:

输入:System.Web.UI.ClientIDMode 指示如何生成 ClientID 属性的值。

自动识别码 ClientID 值是通过连接 ID 值生成的 每个父命名容器与控件的 ID 值。在 一个控件的多个实例的数据绑定场景 呈现时,在控件的前面插入一个递增值 标识值。每个段由下划线字符 (_) 分隔。 该算法在早于 ASP.NET 4 的 ASP.NET 版本中使用。

静态 ClientID 值设置为 ID 属性的值。如果 该控件是一个命名容器,该控件用作顶部 它包含的任何控件的命名容器的层次结构。

可预测 此算法用于数据绑定的控件 控制。 ClientID 值是通过连接 父命名容器的 ClientID 值与 控制。如果控件是一个数据绑定控件,它会生成 多行中指定的数据字段的值 ClientIDRowSuffix 属性添加在末尾。对于 GridView 控件,可以指定多个数据字段。如果 ClientIDRowSuffix 属性为空,序号添加在 结束而不是数据字段值。这个数字从零开始,并且 每行加 1。每个段由一个 下划线字符 (_)。

继承 该控件继承其 NamingContainer 控件的 ClientIDMode 设置。这是默认设置。

【讨论】:

IN OTHER WORDS,使用静态模式强制ASP不改变id 这是最好的答案【参考方案2】:

而不是使用这个选择器

$('#Label1')

用这个,基本上你用的是经典的asp内联服务器端代码。

$('#<%= Label1.ClientID %>')

这将插入生成的任何 ID 以作为文字放置。

如果您希望使用外部文件,那么我建议您在页面上创建一个全局 obj 来保存您的所有客户端 ID,然后在您的外部文件中引用该 obj(不理想,但它是一种解决方案)

var MyClientIDs = 
    Label1 = '<%= Label1.ClientID %>',
    Label2 = '<%= Label2.ClientID %>',
    Textbox1 = '<%= Textbox1.ClientID %>',
    Textbox2 = '<%= Textbox2.ClientID %>'
;

然后在您的外部文件中,您可以访问 Label1,例如:$('#' + MyClientIDs.Label1)

【讨论】:

问题在于它不能在外部javascript文件中使用 梦想:function getLabel1Id() return '#'; - 如果你把它放在 aspx 文件中,你可以从你的 js 文件中调用它。 抱歉 - 我发现这是一个糟糕的解决方案,因为它不鼓励使用外部 js 文件,这是最佳实践。 还有一个问题——一旦你把服务器标签放到你的页面中,如果你尝试添加动态控件,你会得到一个异常。 @Triptych 我同意......解决它的一种方法是在页面上创建一个全局对象,让您可以访问所有客户端 ID。我会用一个例子来更新答案【参考方案3】:

在 .NET 4+ 中设置 ClientIDMode="Static"。这将解决您的问题。

例子:

<asp:Label ID="Label1" ClientIDMode="Static" runat="server" Text="test"></asp:Label>

【讨论】:

【参考方案4】:

您无法阻止 asp.net 生成这些 ID。这就是它的工作方式。

你仍然可以像这样使用 jquery:

$('#<%=label1.ClientID %>').html(xml) 

$('[id$=_label1]').html(xml)

【讨论】:

在 .NET 4 中,您可以使用 ClientIDMode 值阻止 asp.net 生成这些 IDS:***.com/a/8428188/40961。【参考方案5】:

如果并且只有当你的容器布局永远不会改变并且你需要把你的JavaSctipt/jQuery放在一个外部文件,您可以在 jQuery 选择器中使用生成的 id,即

$('#ctl00_ContentPlaceHolder1_Label3').html(xml);

显然,这种方法需要您找出生成的 id 将是什么,并且如果您开始更改站点/应用程序结构,则需要谨慎。

否则,您的最佳选项是

1. 使用内联服务器端代码标记。这种方法的缺点是您不能将 js 代码放在外部文件中 -

$('#<%= Label3.ClientID %>').html(xml);

2. 在您需要在 jQuery 中使用的每个控件上定义唯一的 CSS 类,这仍然允许您将 js 代码放在外部文件中 -

<asp:Label ID="Label3" runat="server" Text="test" CssClass="label3">
</asp:Label>

$('.label3').html(xml);

3. 使用 jQuery 选择器对原始 id 进行模式匹配,这再次允许您将 js 代码放在外部文件中 -

$('[id$=Label3]').html(xml);

这个 jQuery 选择器将选择所有具有 id 属性且值以 Label3 结尾的元素。我可以看到这种方法的唯一潜在缺点是,理论上,可以在一个母版页和两个内容页中拥有一个 ID 为 Label3 的 Label 控件。在此示例中,使用上面的 jQuery 选择器将匹配所有三个标签,这可能会产生不良后果。

编辑:

我认为提高您对IDOverride control 的关注可能会有所帮助。一个Example page can be found here

它允许您指定在呈现 HTML 页面时,哪些控件应该在输出的 HTML 标记中使用 .aspx 文件中给出的 id 覆盖其损坏的 id。我只用一个母版页和面板简单地玩过它,但它似乎运行良好。使用它,您可以在 jQuery 选择器中使用原始 id。但是请注意,如果您在母版页和内容页中拥有具有相同 ID 的控件,这些控件组合起来呈现一个页面的 HTML,则结果是不可预测的。

【讨论】:

非常好的答案。我认为使用 jQuery 会使占位符之类的东西过时,但您完整而权威地回答了实际问题! IDOverride 的页面似乎消失了。我在网上找遍了,找不到。有人在任何地方发布过副本吗?我有一个可以真正从中受益的简单网站,但目前我无法等到 ASP.Net 4.0 或学习 MVC。【参考方案6】:

简短的回答,不要担心使用 asp.net ID。在 asp.net 中,您可以将自己的属性添加到标签:

<asp:TexBox ID="myTBox" runat="server" MyCustomAttr="foo" />

然后在 jquery 中你可以通过以下方式引用这个元素:

$("input[MyCustomAttr='foo']")

我一直使用 jQuery 来做这件事。希望对您有所帮助。

【讨论】:

如果您在自定义属性前加上data-,则它是有效的html5【参考方案7】:

您可以调用类名而不是使用 ID

例如;

$('.CssClassName'). ...

或者,如果您在 MasterPage 的第一行键入此内容,您的控件 ID 将不会改变:

ClientIDMode="Static"

例如;

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="Main_MasterPage" ClientIDMode="Static" %>

【讨论】:

【参考方案8】:

内联代码是正确的方法。但是,这将在 ASP.NET 4.0 中发生变化。我们花了一些时间添加一个允许完全控制在客户端生成的 ID 的功能。以下是网络上有关此功能的一些资源。

http://blog.osbornm.com/archive/2009/01/06/asp.net-4.0-clientid-overview-again.aspx http://channel9.msdn.com/shows/10-4/10-4-Episode-3-ASPNET-WebForms-40/

【讨论】:

【参考方案9】:

这里的大多数建议都可以,但是 jQuery 代码的测试结果表明纯 ID 选择器是迄今为止最快的。我最常用的一个:

$("[id$=origControlId]")

速度很慢,但问题不是太明显,除非页面有很多控件和很多 jQuery。

由于将多个类分配给一个控件相当容易,因此您可以为每个类分配一个与 ID 匹配的 CSSClass。由于它们将是唯一的(您必须观看生成多个控件的中继器类型控件),您可以按类进行选择。

例如:

<asp:Label ID="Label1" CssClass="Label1 SomeOtherClass" runat="server" Text="test">
</asp:Label>

可以通过以下方式唯一选择:

$(".Label1")

几乎与 ID 选择一样快。

我从来没有考虑过这个:

$('#<%= Label1.ClientID %>')

但我要试试!

【讨论】:

【参考方案10】:

您必须将控件的 ClientID 传递给 javascript 代码(我怀疑 Label1 是否被重命名为 Label3)

ClientScriptManager.RegisterClientScriptBlock(GetType(), "someKey", 
    "$('#" + Label1.ClientID + "').html(xml);", true);

【讨论】:

【参考方案11】:

您可以使用ClientID(就像其他人所说的那样),但问题是它不能在外部 JavaScript 文件中使用。

因此,理想情况下,不要使用 ID 从 jQuery 中引用它,而是使用 CSS 类

<asp:Label ID="Label1" runat="server" Text="test" CssClass="myclass"></asp:Label>

然后你可以像这样引用它:

$(".myclass")

【讨论】:

【参考方案12】:

您可以将 ClientID 和 UniqueID 覆盖为this fella did。

/// <summary>
/// Override to force simple IDs all around
/// </summary>

public override string UniqueID

    get
    
        return this.ID;
    


/// <summary>
/// Override to force simple IDs all around
/// </summary>

public override string ClientID

    get
    
        return this.ID;
    

【讨论】:

这不是一个好主意。如果您有一个复杂的控件并且其中一个嵌套控件正在执行此操作。您可以轻松地在页面上使用具有共同 ID 的多个控件来实现,这不是您想要的。【参考方案13】:

您还可以创建一个从 Label 继承的自定义控件,该控件将 ID 属性覆盖为您想要的。

【讨论】:

【参考方案14】:

这可以通过在呈现控件时将 asp.net id 替换为原始 id 来实现。 这非常简单,可以通过创建一组自定义控件来完成。

http://www.bytechaser.com/en/articles/ts8t6k5psp/how-to-display-aspnet-controls-with-clean-id-value.aspx

【讨论】:

【参考方案15】:

冒着明显变化的风险:

<asp:Label ID="Label1" runat="server" Text="test"></asp:Label>

<Label ID="Label1" Text="test"></Label> 

【讨论】:

【参考方案16】:

您需要将属性ClientIDMode="Static" 放在您的按钮中,这使得ID 在运行时将是相同的,这是您在Javascript 中获取对象所需要的。

【讨论】:

【参考方案17】:

您无需“阻止”asp.net 更改控件 ID 即可使用 jquery 或 javascript。

在您的页面上呈现的 id 是控件的 ClientID 属性,而您在控件本身上设置的是 ID。您不能设置 ClientID 属性,它是为您生成的,可能与您的 ID 相同也可能不同。但是,正如其他人所提到的,您可以在您的 aspx 中使用 ClientID 属性:

$('<%= Label1.ClientID %>').html()

或通过使用 ClientScriptManager 方法之一在您的代码隐藏文件中注册客户端脚本。

【讨论】:

【参考方案18】:

只需去掉占位符。或者按类或 DOM 层次结构选择。甚至在不得已的情况下使用 ID 上的部分匹配。在 jQuery 中选择元素有很多简单、干净的方法,我们需要摆脱旧的、丑陋的 ASP.NET 习惯。

Dreas Grech 将最后一颗钉子钉在棺材上。您不能将外部脚本文件与 $('#') 类型的解决方案一起使用。

迈克

【讨论】:

【参考方案19】:

您仍然可以使用 PlaceHolders 并在 PlaceHolder 标签中设置 ClientIDMode

<asp:ContentPlaceHolder ID="BodyContent" runat="server" ClientIDMode="Static">        
</asp:ContentPlaceHolder>

不会更改包含的控件 ID。

【讨论】:

【参考方案20】:

简单,重写控制类。这是一个带有 HtmlGenericControl 的示例,但您可以使用任何 ASP.Net 控件来实现:

public class NoNamingContainerControl : HtmlGenericControl

    public NoNamingContainerControl(string tag) : base(tag)  
    public override string ClientID
    
        get
        
            return this.ID;
        
    

【讨论】:

以上是关于如何阻止 ASP.NET 更改 ID 以使用 jQuery的主要内容,如果未能解决你的问题,请参考以下文章

更改导航 ID 以突出显示当前页面 ASP.NET 的编程解决方案

Firefox 阻止对 ASP.NET 身份更改/模拟的简单 CORS 请求

登录asp.net后如何更改会话ID

asp.net C# 如何以编程方式更改 Page_Load 上的正文背景图像

如何获取 asp.net 身份以从​​数据库中获取对声明的更改?

ASP.NET 核心策略检查中缺少“aud”声明会阻止授权,但它位于 id 令牌中