如何使用JQuery,按ID和ASP.NET选择元素,而不在代码中放置ctl00_

我有大约600多个类似于以下代码的引用…

$("#ctl00_ContentMainPane_eliteUser").html 

并且更改了主模板,只是为了找到所有已经破坏的代码,由于控件层次结构的变化。

所有的javascript都包含在单独的文件中,所以我不能使用这样的代码……

 $("#").html 

我希望有一个很好的解决方案来解决这个问题,以便在修复一次之后,如果模板将来发生变化,我不必修改所有代码。

如何在母版页中定义JavaScript函数,例如:

 function getContainerId() { return "<%=ContentMainPane.ClientID %>"; } 

然后在您包含的JavaScript文件中执行以下操作:

 $("#" + getContainerId() + "_eliteUser"); 

一种方法是使用在每个页面顶部写出的js变量对象。 然后,您的外部js可以使用所需的属性引用设置对象。 这样,您可以更改aspx页面中的id,而无需在外部js文件中对任何内容进行硬编码。

然后,您可以公开一个materpage或基页方法,该方法允许每个页面将控件ID项添加到列表中。 然后,基本方法有责任在每个页面的顶部写出pageVars脚本。

Rick Strahl 在这里谈到这一点

我更喜欢这种方法,因为你仍然可以获得快速选择器的好处。

例如

如果你让aspx写出以下脚本。

 var pageVars = { idList: { eliteUser : 'ctl00_ContentMainPane_eliteUser', normalUser : 'ctl00_ContentMainPane_normalUser', powerUser : 'ctl00_ContentMainPane_powerUser', ..... } }; 

然后在你的外部js

 $('#' + pageVars.idList.eliteUser) $('#' + pageVars.idList.powerUser)....etc 

你可以这样做:

 $("input[id*=eliteUser]").html() 

但是如果你有多个控件在eliteUser中结束他们的ID – 它将无法工作。

我一直在使用扩展WebControl的类,基本上和RedSquare的建议一样 。 我在这个博客上阅读了这个建议

 ///  /// Custom Web control that renders two JavaScript functions out into the page /// so that defined control IDs can be used to get a reference to HTML DOM elements ///  [DefaultProperty("Text")] [ToolboxData("<{0}:ClientIdHandler runat=\"server\">")] public class ClientIdHandler : WebControl { private StringBuilder _builder = new StringBuilder(); public ClientIdHandler(){} ///  /// Renders the ClientID of the control in JavaScript function "clientId" to the specified writer. ///  /// A  whose ClientID will be included /// in the rendered HTML output. public void AddControl(Control c) { _builder.AppendFormat(" case '{0}': return '{1}'; break;" + Environment.NewLine, c.ID, c.ClientID); } ///  /// Overrides the Render method to prevent a Start and End  /// being rendered in the HTML for the control. ///  /// A  that represents /// the output stream to render HTML content on the client. protected override void Render(HtmlTextWriter writer) { RenderContents(writer); } ///  /// Renders the contents of the control to the specified writer. ///  /// A  that represents /// the output stream to render HTML content on the client. protected override void RenderContents(HtmlTextWriter output) { output.Write("" + Environment.NewLine); } } 

然后你可以在aspx页面或代码隐藏中使用

  protected override void OnInit(EventArgs e) { ClientIdHandler clientIds = new ClientIdHandler(); clientIds.AddControl(myControl); this.Controls.Add(clientIds); base.OnInit(e); } 

这将在页面中呈现以下内容

  

因此,在外部JavaScript文件中,您可以使用以下内容

 // for jQuery selectors var myControl = $('#' + clientId('myControl')); // for vanilla JavaScript var myControl = getElementByClientId('myControl')); 

据我所知,asp.net不会乱用类名。 向控件添加类名,并在代码中将该名称用作引用。

我正在使用ScriptManager.RegisterStartupScript来获取我需要的所有ClientID。

  1. 在页面的“head”中定义javascript变量以存储ID。
  2. 使用Page_Load中的RegisterStartupScript为变量赋值,如下所示:

string myScript = String.Format(“window.onload = function(){id1 = {0},id2 = {1},id3 = {2}}”,Control1.ClientID,Control2.ClientID,Control3.ClientID);

ScriptManager.RegisterStartupScript(Page,Page.GetType(),“SomeKey”,myScript,true);

这是一个我明白将在Visual Studio的下一个版本中解决的问题,但是我意识到这对你没有帮助。

我们在项目中解决这个问题的方式是:

 $.extend({ clientID: function(id) { return $("[id$='_" + id + "']"); } }); 

以及使用它的代码:

 statusBar = $.clientID("MSS_MESS_LINE_Static")