如何使用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\">{0}:ClientIdHandler>")] 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。
- 在页面的“head”中定义javascript变量以存储ID。
- 使用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")