繁体   English   中英

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

[英]Reference ASP.NET control by ID in JavaScript?

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

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

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

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>

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

您可以将控件的ClienIDMode属性更改为'Static' ,这将导致您在.NET代码中为控件提供相同的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 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;
}

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

对于'ctl00_ContentMain_Button1' - 在asp.net中,当浏览器中的页面呈现时,第一部分保持相同的'ctl00'。 第二部分是使用'ContentMain'的ContentPlaceHolder的ID。 第三个是控件'Button1'的ID

我喜欢这个http://codedotnets.blogspot.in/2012/01/how-get-id-server-control-javascript.html

我更喜欢标记document.getElementById('<%#TextBox1.ClientID%>')。value中的数据绑定标记,而不是使用服务器端标记实现<%= TextBox1.ClientID%>。

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

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

this.Form.Controls.Add(myContorl);

在运行时生成此错误:

无法修改Controls集合,因为控件包含代码块(即<%...%>)。

不幸的是,在构建完网站后,这通常只会变得非常明显。

当实现数据绑定控件'<%#TextBox1.ClientID%>'解析标记中引用的控件属性的值时,在适当的位置,例如Page_Load数据绑定结束,如下所示:

的Page.DataBind()

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

TextBox1.DataBind()

应用程序的发展最终会导致某些基本站点范围的功能,您可能希望添加基本控件,一旦您使用服务器端标签填充您的网站应用程序,用数据绑定替换它们就会出现问题,尤其是当页面编码为处理数据绑定时他们自己。

我不认为这样做有一个“最佳实践”。 有很多不同的相当好的做法。 这是我们的:

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

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

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

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

哦,我也找到了这个,以防其他人遇到这个问题。

为asp.net控件使用自定义jQuery选择器: http//john-sheehan.com/blog/custom-jquery-selector-for-aspnet-webforms/

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM