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

在JavaScript中按ID引用ASP.NET控件?,javascript,asp.net,ajax,Javascript,Asp.net,Ajax,当呈现ASP.NET控件时,它们的ID有时会更改,就像它们位于命名容器中一样按钮1在渲染时可能实际具有ctl00\u ContentMain\u按钮1的id 我知道您可以在.cs文件中以字符串形式编写JavaScript,获取控件的clientID,并使用clientscript将脚本注入页面,但是有没有一种方法可以使用ASP.NET Ajax直接从JavaScript引用控件 我发现编写一个函数递归地解析dom并找到一个包含我想要的id的控件是不可靠的,所以我一直在寻找一个最佳实践,而不是解决

当呈现ASP.NET控件时,它们的ID有时会更改,就像它们位于命名容器中一样<例如,代码>按钮1在渲染时可能实际具有
ctl00\u ContentMain\u按钮1
的id

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


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

我认为没有一个“最佳实践”可以做到这一点。有很多不同的非常好的实践。这是我们的:

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

<span id="something_crazy_long">
    control markup
</span>
<script type="text/javascript">new CustomControl('something_crazy_long');</script>
在codebehind中,我们执行以下操作:

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");
}

对此有几点想法:

1) 我很幸运地通过css类而不是id获取元素,因为asp.net id不像您所说的那样可靠。我使用此功能,并且它的性能相当好:

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;
}
函数getElementsByClass(搜索类、节点、标记){
var classElements=新数组();
if(node==null)
{
节点=文档;
}
if(标记==null)
{
标记='*';
}
var els=node.getElementsByTagName(标记);
var elsLen=els.长度;
var pattern=newregexp(“(^ |\\s)”+searchClass+”(\\s |$)”;
对于(i=0,j=0;i
2) jQuery在这方面很有帮助。使用jQuery可以可靠地获取id以特定字符串结尾的元素。虽然这不是使用jQuery的“理由”,但绝对是一个优点


3) 这将在asp.net 4.0中得到修复,因此请继续:-)

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


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

Dave Ward的这篇文章可能有您想要的:

文章节选:

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

$get('<%= TextBox1.ClientID %>')
$get(“”)
现在正确的客户机元素ID是 引用,而不考虑 页面的结构和嵌套 控制水平。在我看来, 非常轻微的性能成本 这种方法很值得一试 您的客户端脚本编写更具弹性 改变

还有Dave在那篇文章评论线程中的一些示例代码:

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

警报('TextBox1的值为:'+$get(''.value));

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

哦,我也发现了这一点,以防其他人有这个问题

对asp.net控件使用自定义jQuery选择器:

您也可以使用
document.getElementById
方法获取ID。

对于asp.net中的“ctl00\u ContentMain\u Button1”-当页面在浏览器中呈现时,第一部分保持不变的“ctl00”。第二部分是使用“ContentMain”的ContentPlaceHolder的ID。第三个是控件“Button1”的ID


我喜欢这个

与使用服务器端标记实现相比,我更喜欢标记文档.getElementById(“”).value中的数据绑定标记

服务器端标记禁止在代码隐藏中向dom添加控件。这种需求通常会在构建应用程序时出现,而数据绑定方法可能会使您免于重大重写

使用服务器端标记时,也称为执行此常见操作的“代码块”

this.Form.Controls.Add(myContorl)

在运行时生成此错误:

无法修改控件集合,因为控件 包含代码块(即)

不幸的是,这通常只有在你建立了你的网站之后才会变得明显

实现数据绑定控件“”时,请在适当的位置(如页面末尾)解析标记中引用的控件属性的值。加载数据绑定如下:

Page.DataBind()

请记住Page.DataBind()会导致页上的子控件也进行数据绑定,如果页单独处理某些子控件的数据绑定,这可能会产生不必要的副作用。如果是这种情况,可以对单个控件执行数据绑定,如下所示:

TextBox1.DataBind()


应用程序的发展最终会带来一些基本站点范围的功能,在这些功能中,您可能需要添加基本控件,一旦您在网站应用程序中添加了服务器端标记,用数据索引替换它们就会出现问题,尤其是当页面被编码为自己处理数据绑定时。

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

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

将导致:

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


所以你有相同的身份证。

谢谢,雷克斯。我想知道是否可以通过前端js来实现这一点。但是很有意思的是,我们可以通过改变渲染来找到另一种方法。谢谢,Brendan。由于还没有内置的方式,2似乎是最好的选择。我已经在项目中使用jquery了。它确实与我的搜索函数有相同的问题,那就是我可能想要“box”,它会找到控件“someotherbox”,但这比等到201更好
<input name="ctl00$MainContent$TextBox1" type="text" id="TextBox1">