在asp.net中检索javascript代码的客户端ID无效

在asp.net中检索javascript代码的客户端ID无效,javascript,asp.net,Javascript,Asp.net,对于网站,已定义usercontrol ascx为用户提供计算帮助。 该控件在另一个ascx控件中执行多次,该控件是umbraco网站的一部分 用户控件中的一些面板已经隐藏,我正试图通过使用java脚本来显示它们 用于选择要显示的面板的asp代码: <asp:Panel ID="firstpanel" runat="server"> <asp:RadioButtonList ID="rblSelect" runat="server" RepeatDirection="Ver

对于网站,已定义usercontrol ascx为用户提供计算帮助。 该控件在另一个ascx控件中执行多次,该控件是umbraco网站的一部分

用户控件中的一些面板已经隐藏,我正试图通过使用java脚本来显示它们

用于选择要显示的面板的asp代码:

<asp:Panel ID="firstpanel" runat="server">
  <asp:RadioButtonList ID="rblSelect" runat="server" RepeatDirection="Vertical" >
     <asp:ListItem Text="Show hidden" Value="0" onclick="ShowMe('<%= hiddenPan.ClientID %>');" ></asp:ListItem>
     <asp:ListItem Text="Show other" Value="1" onclick="ShowMe('<%= otherPan.ClientID %>');" ></asp:ListItem>
  </asp:RadioButtonList>
</asp:Panel>

<asp:Panel ID="hiddenPan" runat="server" style="display:none">
  <!-- stuff to work with -->
</asp:Panel>
这种方法行不通。控制台日志返回的是值,而不是我期望的clientID

我尝试过的解决方案: 实现静态客户端ID->由于ascx控件被实现多次,这将导致javascript显示和隐藏它找到的第一个控件,而不是活动控件

我已经尝试了这个解决方案,但它不适合我

我的问题是如何切换示例中面板的显示。我们也欢迎您提供良好的解决方案。

****

我不确定,但可能是因为ListItem属性将所有值转换为字符串,请检查以下内容:

<asp:ListItem Text="<%= hiddenPan.ClientID %>" Value="0"></asp:ListItem>

唯一的问题是,每个PanelID不应作为另一个PanelID的子字符串,还应使用divUserControlContainer类将每个UserControl包装为div。

您可以使用JQuery使用其他解决方法:

在jQuery端:

/// $("[id*=rblSelect] input").live("click", function () { -- old jquery way

// new version of Jquery uses 'on' instead of 'live'
$("[id*=rblSelect]").on("click", "input", function () 
{ 
     var selectedValue = $(this).val();
     if (selectedValue == "0") // IF first item is clicked
     {
          $('#' + '<%=hiddenPan.ClientID %>').show();
     } else {
         $('#' + '<%=otherPan.ClientID %>').show();
     }
 });

显然,如果引号用于某些属性(如ListItem的“onclick”属性)中,ASP.NET解析器会将引号编码为其HTML等价物。我不太清楚这种行为,但这只是一个例子

为了解决您的问题,我建议采取以下解决方法:在onclick属性中只放置控件的名称,然后在控件的OnPreRender方法中找到该控件并创建一个具有其客户端ID的变量。我选择了PreRender,因为客户端ID都是在这一点之前分配的

在控件的标记中,只需放置面板的服务器端Id:

<asp:ListItem Text="Show hidden" Value="0" onclick="hiddenPan"></asp:ListItem>
<asp:ListItem Text="Show other" Value="1" onclick="otherPan" ></asp:ListItem>
这将添加到呈现的输出HTML中,每个列表项都有一个变量,如下所示:

<script type='text/javascript'>var uc1_hiddenPan_id = 'uc1_hiddenPan';</script>
 onclick="ShowMe(uc1_hiddenPan_id);"

更新:我已经编辑了答案,以便按照OP的要求使用多个控件。

目前,我已经在客户端通过javascript进行了以下修改:

<div id="containerDiv">
  <asp:Panel ID="firstpanel" runat="server">
    <asp:RadioButtonList ID="rblSelect" runat="server" RepeatDirection="Vertical" >
       <asp:ListItem Text="Show hidden" Value="0" onclick="ShowMe($$(this, 'hiddenPan'));" ></asp:ListItem>
       <asp:ListItem Text="Show other" Value="1" onclick="ShowMe($$(this, 'otherPan'));" ></asp:ListItem>
    </asp:RadioButtonList>
  </asp:Panel>

  <asp:Panel ID="hiddenPan" runat="server" style="display:none">
    <!-- stuff to work with -->
  </asp:Panel>
</div>
javascript/客户端函数:

function ShowMe(showPanel) {
   showPanel.show();
}

function $$(target, id) {

    var t = $(target);
    var con = t.closest("#containerDiv");
    var el = $("#" + id, con);
    if (el.length < 1)
        el = $("[id$=_" + id + "]", con);

    return el;
}

以下是解决方案。

这很奇怪。你能检查并看看这段代码是否在IIS下动态运行吗?我能在IIS中看到吗?如果这段代码在一个ASPX页面中运行,而该页面在一个定义为应用程序的虚拟目录中,那么是的。我检查了,是的,它是动态运行的。这是我问的一个愚蠢的问题!打扰一下我正在试图找到一种方法,只有当客户端ID模式设置为静态时,这种方法才会起作用。ClientIDMode=静态,仅适用于第一个控件。第二个控件不起作用。不,不起作用,您不需要设置ClientIDMode=static,第二个控件也起作用,请在写评论之前检查答案的代码。它适用于所有面板,而不仅仅是一个面板。我正在处理同一个usercontrol的多个实例,这会取消其中每个实例中的面板的隐藏。我完全理解您的问题在您最后的评论之后,我编辑了答案,您可以检查新的答案,在编辑的代码中,每个usercontrol分别工作,当您单击ListItem时,jquery搜索他的divUserControlContainer容器,当找到它时,只在同一个divUserControlContainer中显示选定的面板,而不更改其他divUserControlContainers读取其他UserControls。发生了什么事?你能详细说明一下吗?由于我在这里制作了一个示例及其运行,我将代码添加到Javascript页面。我添加了一些控制台日志记录,但它们没有出现在firebug上。不幸的是,这种方法总是在页面的第一个用户控件上显示和隐藏面板,而不是第二个。我终于理解了这个问题。您应该将代码移动到控件的PreRender事件。你能在我从理发店回来之前测试一下吗?@martijn我已经更新了答案。它可以按你的意愿工作。祝你好运
public partial class WebUserControl1 : System.Web.UI.UserControl
{
    protected override void OnPreRender(EventArgs e)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder("<script type='text/javascript'>");
        foreach (ListItem i in rblSelect.Items)
        {
            string relatedControlId = i.Attributes["onclick"];

            Control relatedControl = null;
            if (!string.IsNullOrEmpty(relatedControlId) && (relatedControl = FindControl(relatedControlId)) != null)
            {
                sb.AppendFormat("var {0}_id = '{0}';", relatedControl.ClientID);
                i.Attributes["onclick"] = string.Format("ShowMe({0}_id)", relatedControl.ClientID);
            }
        }
        sb.Append("</script>");
        this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), string.Format("ids{0}", this.ID) , sb.ToString());

        base.OnPreRender(e);
    }
<script type='text/javascript'>var uc1_hiddenPan_id = 'uc1_hiddenPan';</script>
 onclick="ShowMe(uc1_hiddenPan_id);"
<div id="containerDiv">
  <asp:Panel ID="firstpanel" runat="server">
    <asp:RadioButtonList ID="rblSelect" runat="server" RepeatDirection="Vertical" >
       <asp:ListItem Text="Show hidden" Value="0" onclick="ShowMe($$(this, 'hiddenPan'));" ></asp:ListItem>
       <asp:ListItem Text="Show other" Value="1" onclick="ShowMe($$(this, 'otherPan'));" ></asp:ListItem>
    </asp:RadioButtonList>
  </asp:Panel>

  <asp:Panel ID="hiddenPan" runat="server" style="display:none">
    <!-- stuff to work with -->
  </asp:Panel>
</div>
function ShowMe(showPanel) {
   showPanel.show();
}

function $$(target, id) {

    var t = $(target);
    var con = t.closest("#containerDiv");
    var el = $("#" + id, con);
    if (el.length < 1)
        el = $("[id$=_" + id + "]", con);

    return el;
}