菜单项的ClientID

本文关键字:ClientID 菜单项 | 更新日期: 2023-09-27 18:17:13

我在页面上有一个项目,它有一系列MenuItems(从数据库动态生成)作为菜单项。

每个菜单项将自己呈现为

<a class="ctl00_cphContent_cphMainContentTitle_uxHeaderMenu_menuPageNav_1 button ctl00_cphContent_cphMainContentTitle_uxHeaderMenu_menuPageNav_3" style="border-style:none;font-size:1em;" href="SomeURLHere.aspx">

然而,我想得到这个链接的ClientID(我们使用一个外部Javascript库弹出页面在模态灯箱样式框架)。其中一个要求是,我们需要识别"可点击对象ID",这样我们就可以将其设置为能够在点击时触发事件。

我们网站的其他地方都有

OurSite.SetupDialogueBoxForOpen('<%= HyperLink.ClientID =>');

然而,由于某些原因,菜单项似乎没有为其分配ClientID属性。这使得在JavaScript中设置客户端id几乎不可能。

有没有人知道如何获得菜单项的ClientID(只是为了澄清菜单项的类型是System.Web.UI.WebControls.MenuItem

)

提前感谢!

菜单项的ClientID

如果你想改变控件中项目的呈现方式,你可以使用StaticMenuItemTemplateDynamicMenuItemTemplate属性。在我的示例中,我将只使用第一个(静态,用于顶级项):

<asp:Menu runat="server" ...>
  <StaticMenuItemTemplate>
    <a id="<%# GetSuitableClientId(Container) %>"><%# Eval("Text") %></a>
  </StaticMenuItemTemplate>
</asp:Menu>

StaticMenuItemTemplate属性是ITemplate类型的,并且与此类模板属性通常的情况一样,它被TemplateContainer属性装饰。这指定要在其中实例化模板的容器,通常容器提供对呈现中可能需要的一些上下文的访问。在本例中,它的类型是MenuItemTemplateContainer,它实现了IDataContainer,从而提供了对数据项的访问。

因此,我们将这个容器传递给页面中的方法,并在该方法中构造一个我们认为合适的ID。我们可以使用数据项表示深度,容器表示索引,例如:

protected string GetSuitableClientId(MenuItemTemplateContainer container)
{
  MenuItem item = (MenuItem)container.DataItem;
  return String.Format("menuItem-{0}-{1}", item.Depth, container.ItemIndex);
}

我猜想在构造这个答案时,您现在可以调整JavaScript以绑定到<a id="menuItem-2-4">Text</a>元素上的单击事件,因为您现在有了可预测的客户端id。

编辑:你也可以在你的模板中使用下面的内容,让ASP。. NET负责创建唯一的客户端ID,但这是不可预测的…

<asp:HyperLink ID="MenuItem" runat="server" NavigateUrl='<%# Eval("NavigateUrl") %>' />

如何获取DOM中每个锚标记的列表并通过它们迭代查看。class,直到找到class=="whatever_Nav_ID_or_flag_you_entered_or_somehow_can_tell_this_element_apart",然后使用。id分配id给它?例如:未测试

var anchors = document.getElementsByTagName("a");
for(int i = 0; i < anchors.length()){
    if(anchors[i].class=="testClass"){
        anchors[i].id = "targetThisAnchor";
        break;
    }
}

编辑:在渲染过程中,你可以使用一个条件来查看新的菜单项是否是你想要的。

<%
  if (MenuItem.flag == menuItemToTarget)
  {
      //set MenuItem id
  }
%>

试试这个,改变selector $("menu > a").bind('click',function(){}));

你会得到这样的菜单项:

OurSite.SetupDialogueBoxForOpen('<%= uxHeaderMenu.FindControl("menuPageNav_3").ClientID %>');

因为你没有发布任何代码,我不能告诉你如何具体选择第三个(在上面的情况下)....但是这应该可以工作。

你需要使用FindControl,因为MenuItem是Menu的子元素,而不是Page或User Control的子元素。

Asp:menu提供了一组CSS属性,例如hoverCss/SelectCss。

如果你选择(鼠标over/点击)一个菜单项,cssclass会添加到html控件(a)上吗?

如果答案是"是",则使用

$ (' .thecssclassuspecified ') .live("点击",函数(){

                                $(this)....
                              });

或'No',恐怕你必须使用类似下面的代码,因为VS 2010之前的asp控件对js和jquery来说并不完美。

$('菜单比;一个")。生活("点击",函数(){

                       $(this)... 
               });

当绑定菜单(OnMenuItemDataBound)时,您可以添加带有一些ID的自定义属性,这些ID可以稍后在JavaScript中使用。

Update: MenuItem没有Attributes属性,所以它是死胡同。此外,由于MenuItem是密封的,因此没有更改的余地。但是Menu是公共类,所以也许可以在这里完成。这整个菜单/菜单项是不修改友好的,所以我认为你必须写很多自定义代码。

或者使用适配器

如果由我来决定,我会放弃asp.net菜单,完全自定义编写。

这些答案大多提供了针对某个链接并对其进行处理的好主意。问题是,您不知道数据库将产生哪些链接,并且它们没有可选择的客户端ID集。

你可能不喜欢这个答案,但最终你需要实现一些东西,使你能够识别链接,无论它是class还是id属性最终是无关紧要的。

大致的想法可能是:

  • 客户端编号/命名约定。例如,在页面上准备使用jQuery来解析锚,可能是它们的类或href值,并使用这些数据来常规设置客户端Id。

  • 修改DB模式,允许客户端ID与链接详细信息一起存储。这可能需要做最多的工作,因为这意味着要改变模式、对象和方法等等。但这不应该太难,而且可能是你最安全、最干净的解决方案。

我相信还有其他的选择,但是关键是你需要在脚本帮助你之前以某种方式识别你的链接。