21

我现在是一名信息架构师和 JavaScript 开发人员,但最近我又重新开始了后端编码。而且,在尝试集成一个 HTML 原型并与我们基于 C# 的 CMS 一起工作时,我与我们的程序员对 .NET 任意重写表单元素的 HTML ID 属性发生了争执。

我可以理解 .NET 更改 ID 的代码隐藏推理,但是在尝试开发例如 jQuery 增强接口时您不能再使用 ID 的事实引起了一些摩擦。我能做些什么来解决这个问题?

我已经尝试使用 class 属性,但这真的很糟糕,不是它的意思,也没有解决 .NET 有效地动态更改渲染源的问题。这也意味着 CSS 现在没那么有用了,创建和维护的效率也越来越低。

任何提示或建议都非常感谢 - 任何少一些不眠之夜的东西......

4

10 回答 10

25

简短的回答是否定的,对于 webforms,id 总是可以根据元素的嵌套来重写。您可以通过 ClientID 属性访问 id,因此您可以在页面/控件末尾的脚本中将 id 设置为变量,然后将它们放入 jQuery。

像这样的东西:

<asp:button id="ImAButton" runat="server">Click Me</asp:button>

<script type="text/javascript">
var buttonId = "<%=ImAButton.ClientId%>";
$("#"+buttonId).bind('click', function() { alert('hi); });
</script>

我知道这是一个 hack,但它会起作用。(我应该注意未启动的,我在那里使用 Prototype $ get by id 方法)

于 2008-09-02T08:20:29.283 回答
12

一种方法是手动覆盖 ID:

public override string UniqueID
{
  get { return this.ID; }
}
public override string ClientID
{
  get { return this.ID; }
}

Rick Strahl 写了一篇博客文章,提供了有关该方法的更多信息。

于 2008-09-02T08:23:49.290 回答
7

查看 ASP.Net MVC - 它解决了 ASP.Net 默认生成的过度杀伤对象层次结构。

这个网站是用 MVC 写的(我认为)——看看它的结构。如果我现在在做一个新项目,我会先考虑

如果您坚持使用基本的 ASP.Net,请小心覆盖 ClientID 和 UniqueID - 它往往会破坏许多 Web 控件。

我发现的最好方法是将不可读的 ClientID 传递给 Javascript。

于 2008-09-02T09:00:03.900 回答
4

您可以扩展 .net 控件并在调用相关属性时使它们返回实际 id。

ClientID 是 id 属性, UniqueID 是 html 元素的 name 属性。因此,当您创建如下所示的文本框并使用它而不是框架中的文本框时,您使 id 和 name 属性呈现为与服务器端 id 相同。

public class MyTextBox : TextBox
{
    public override string ClientID { get { return ID; } }
    public override string UniqueID { get { return ID; } }
}

要使用这个新的用户控件,基本上就像注册自定义用户控件一样注册这个控件(您可以在 web.config 中进行,这样您就不必在所有页面中都这样做):

<%@ Register Assembly="MyLibrary" NameSpace="MyLibrary.WebControls" TagPrefix="MyPrefix" %>

并像使用文本框一样使用它:

<MyPrefix:MyTextBox ID="sampleTextBox" runat="server" />
于 2008-09-02T08:18:35.963 回答
1

就我个人而言,我使用我开发的一组方法来桥接服务器端 ASP.NET “魔术”(我还没有使用 MS MVC 的东西)和我的客户端代码,因为发生的 ID 会发生变化. 这只是一个可能会或可能不会被证明有用的方法:

public void RegisterControlClientID(Control control)
{
   string variableDeclaration = string.Format("var {0} = \"{1}\";", control.ID, control.ClientID);
   ClientScript.RegisterClientScriptBlock(GetType(), control.ID, variableDeclaration, true);
}

因此,在您的服务器端代码中,您只需调用它并传入您想要为其使用更友好名称的控件实例。换句话说,在设计期间,您可能有一个 ID 为“m_SomeTextBox”的文本框,并且您希望能够使用相同的名称编写 JavaScript - 您只需在服务器端代码中调用此方法:

RegisterControlClientID(m_SomeTextBox);

然后在客户端上呈现以下内容:

var m_SomeTextBox = "ctl00_m_ContentPlaceHolder_m_SomeTextBox";

这样一来,您的所有 JavaScript 代码都可能完全不知道 ASP.NET 决定为变量命名的内容。当然,对此有一些注意事项,例如当您在页面上有多个控件实例时(例如,因为使用了多个用户控件实例,其中所有实例都具有 m_SomeTextBox 的实例),但通常这种方法可能对您最基本的需求有用。

于 2008-09-02T17:48:10.307 回答
1

我通常做的是创建一个接收字段名称的通用函数。它添加通常的“asp.net”前缀并返回对象。

var elemPrefix = 'ctl00-ContentPlaceHolder-'; //replace the dashes for underscores

var o = function(name)
{    
    return document.getElementById(elemPrefix + name)
}

有了它,您可以在 jQuery 中使用这种调用

$(o('buttonId')).bind('click', function() { alert('hi); });
于 2008-09-05T22:55:25.283 回答
1

您绝对不希望将 asp.net 生成的 ID 硬编码到您的 CSS 中,因为如果您以控制树更改的方式重新排列页面上的内容,它可能会更改。

你是对的,CSS ID 有它们的位置,所以我会忽略只使用类的建议。

此处描述的各种 javascript hack 对于一个小问题来说太过分了。从类继承并覆盖 ID 属性也是如此。当你只想重构一些 CSS 时,建议切换到 MVC 肯定是没有帮助的。

只需拥有您使用 CSS 定位的单独的 div 和 span。如果要使用 ID,请不要直接针对 ASP.NET 控件。

  <div id="DataGridContainer">
     <asp:datagrid runat=server id="DataGrid" >
         ......
     <asp:datagrid>
  </div>
于 2008-09-22T01:53:36.320 回答
0

如果您使用 jQuery,那么您可以使用大量的CSS 选择器和 jQuery自定义选择器来定位页面上的元素。因此,您可以执行以下操作,而不是通过它的 id 选择提交按钮:

$('fieldset > input[type="submit"]').click(function() {...});
于 2008-09-09T12:05:25.703 回答
0

我可以看到 .NET 系统感觉不那么直观,但给它一个机会。根据我的经验,它实际上最终会创建更清晰的代码。当然

<asp:button id="ImAButton" runat="server">Click Me</asp:button>

<script type="text/javascript">
var buttonId = <%=ImAButton.ClientId%>
$(buttonId).bind('click', function() { alert('hi); });
</script>

工作正常。但这受到不模块化的影响。你真正想要的是这样的:

<script type="text/javascript">
function MakeAClick(inid)
{
  $(inid).bind('click', function() { alert('hi); });
}
</script>

然后在 java 端或 C# 端使用您的代码调用 MakeAClick。当然,在 C# 方面它更有意义,您只需在其中添加 ClientID。

也许这是您正在审查的代码的真正问题。

于 2009-12-02T22:00:58.690 回答
0

更好的方法是使用 ClientIDMode 并将其设置为static. 您甚至可以在 web.config 文件中为特定页面或全局设置它。然后你再也不用处理这个问题了,你的 JQuery 就更干净了。

页面顶部:

<%@ Page Title="" ClientIDMode="Static" Language="C#" CodeBehind="..." Inherits="WebApplication1.WebForm2"  %>

仅在控制时:

<asp:Panel runat="server"  ClientIDMode="Static"></asp:Panel>
于 2016-02-11T08:32:24.353 回答