在 JavaScript 中通过 ID 引用 ASP.NET 控件?

IT技术 javascript asp.net ajax
2021-03-03 16:46:24

当呈现 ASP.NET 控件时,它们的 id 有时会发生变化,就像它们在命名容器中一样。Button1例如,它实际上可能具有ctl00_ContentMain_Button1何时呈现的 id

我知道您可以在 .cs 文件中将 JavaScript 编写为字符串,获取控件的 clientID 并使用 clientscript 将脚本注入您的页面,但是有没有一种方法可以使用 ASP.NET Ajax 直接从 JavaScript 引用控件?

我发现编写一个函数来递归解析 dom 并找到一个包含我想要的 id 的控件是不可靠的,所以我正在寻找最佳实践而不是解决方法。

6个回答

戴夫·沃德 (Dave Ward) 的这篇文章可能包含您要找的内容:

http://encosia.com/2007/08/08/robust-aspnet-control-referencing-in-javascript/

文章摘录:

确实有。更好的解决方案是使用内联 ASP.NET 代码来注入控件的 ClientID 属性:

$get('<%= TextBox1.ClientID %>')

现在引用了正确的客户端元素 ID,而不管页面的结构和控件的嵌套级别如何。在我看来,这种方法非常小的性能成本非常值得让您的客户端脚本更能适应变化。

以及 Dave 来自该帖子的评论线程的一些示例代码:

<script>
  alert('TextBox1 has a value of: ' + $get('<%= TextBox1.ClientID %>').value);
</script>

我上面链接的文章的评论线程也有一些很好的讨论。

相同,但对于此处的 ASP.NET 控件
2021-04-21 16:46:24

您可以ClienIDMode将控件的属性更改为'Static'将产生与您在 .NET 代码中为控件提供的 ID 相同的 ID。

<asp:TextBox ID="TextBox1" ClientIDMode="Static" runat="server"></asp:TextBox> 

将导致:

<input name="ctl00$MainContent$TextBox1" type="text" id="TextBox1"> 

所以你有相同的ID。

对此的一些想法:

1)我很幸运通过css类而不是id来获取元素,因为asp.net ids并不可靠。我使用这个函数并且它表现得相当好:

function getElementsByClass(searchClass,node,tag) {
 var classElements = new Array();
 if ( node == null )
    {
        node = document;
    }

 if ( tag == null )
    {
        tag = '*';
    }

 var els = node.getElementsByTagName(tag);
 var elsLen = els.length;
 var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");

 for (i = 0, j = 0; i < elsLen; i++) 
    {
        if ( pattern.test(els[i].className) ) 
            {
                classElements[j] = els[i];
                j++;
            }
      }
 return classElements;
}

2) jQuery 在这里有很大帮助。使用 jQuery,您可以可靠地获取 id 以某个字符串结尾的元素。虽然这不是使用 jQuery 的“原因”,但它绝对是一个加分项。

3) 这将在 asp.net 4.0 中修复,所以挂在那里 :-) http://weblogs.asp.net/asptest/archive/2009/01/06/asp-net-4-0-clientid-overview。 aspx

谢谢,布伦丹。由于还没有内置的方式,#2 似乎是最好的选择。我已经在项目中使用了 jquery。它确实与我的搜索功能存在相同的问题,即我可能想要“box”并且它找到了控件“someotherbox”,但总比等到 2010 年要好。
2021-04-17 16:46:24

我认为这样做没有单一的“最佳实践”。有很多不同的非常好的做法。这是我们的:

每个具有客户端功能的控件都会在控件标记的正下方呈现一个内联脚本块:

<span id="something_crazy_long">
    control markup
</span>
<script type="text/javascript">new CustomControl('something_crazy_long');</script>

每个控件都有一个伴随的 JS,如:

var CustomControl = function(id) {
    this.control = document.getElementByID(id);
    this.init();
};

CustomControl.prototype.init = function() {
    //do stuff to wire up relevant events
};

在代码隐藏中,我们执行以下操作:

class CustomControl : Control

override void Render(HtmlTextWriter writer)
{
    writer.WriteBeginTag("span");
    writer.WriteAttribute("id", this.ClientID);
    writer.Write(HtmlTextWriter.TagRightChar);
    //write control markup
    writer.WriteEndTag("span");
    writer.WriteBeginTag("script");
    writer.WriteAttribute("type", "text/javascript");
    writer.Write(HtmlTextWriter.TagRightChar);
    writer.Write(
        string.Format("new CustomControl('{0}');", this.ClientID)
    );
    writer.WriteEndTag("script");
}
谢谢,雷克斯。我想知道是否可以通过前端 js 来做到这一点。但是通过更改渲染来查看另一种方法是很有趣的。
2021-04-24 16:46:24

我做了一些类似于 Rex M 的事情,除了避免多个脚本标签,我在页面基类中使用一个函数来注册我将要使用客户端的控件,然后将它们吐出到 1 个脚本标签内的 html。

您甚至可以子类化您的控件以自动注册函数或使用布尔属性来设置您是否要在客户端使用它们。