【问题标题】:Is it possible to force a menu popout to trigger on click instead of mouseover?是否可以强制在单击而不是鼠标悬停时触发菜单弹出?
【发布时间】:2010-12-10 11:17:13
【问题描述】:

我使用了一个 ASP.NET 菜单控件,Orientation=Horizo​​ntal。弹出菜单出现在鼠标悬停时有点令人恼火,如果当您想单击菜单正下方的某些内容时将鼠标移到菜单上,这会导致它意外显示。然后菜单弹出隐藏你真正想点击的元素!

是否可以更改功能以使弹出窗口需要鼠标单击而不是鼠标悬停?

【问题讨论】:

    标签: asp.net menu webforms


    【解决方案1】:

    好吧,我自己找到了一个解决方案(有点像黑客......)。
    此解决方案需要使用 AJAX 来捕获菜单项 onclick 回发事件,因此可以在单击菜单项时在执行实际回发之前在 javascript 中获取客户端。

    首先,我覆盖了菜单控件定义的这些函数 忽略鼠标悬停事件中的菜单弹出:

    var activeMenuItem = null;
    
    function Menu_HoverStatic(item) {
    
      // Register the active item to be able to access it from AJAX 
      // initialize postback event
      activeMenuItem = item  
    
      // Apply the style formatting on mouseover (colors etc).
      // This was also called in the original Menu_HoverStatic function.
      Menu_HoverRoot(item);  
    
    } 
    
    function Menu_Unhover(item) {
    
        activeMenuItem = null; // This is the only difference to the original
    
        var node = (item.tagName.toLowerCase() == "td") ?
        item:
        item.cells[0];
        var nodeTable = WebForm_GetElementByTagName(node, "table");
        if (nodeTable.hoverClass) {
            WebForm_RemoveClassName(nodeTable, nodeTable.hoverClass);
        }
        node = nodeTable.rows[0].cells[0].childNodes[0];
        if (node.hoverHyperLinkClass) {
            WebForm_RemoveClassName(node, node.hoverHyperLinkClass);
        }
        Menu_Collapse(node);
    } 
    
    
    // Then I added a renamed copy of the original `Menu_HoverStatic` function:
    function Menu_ClickStatic() {
        // Pick up the active menu item that is set in the 
        // overridden Menu_HoverStatic function.
        // In the original, the item was input parameter.
        var item = activeMenuItem;
    
        // The rest is identical to the original Menu_HoverStatic.
        var node = Menu_HoverRoot(item);
        var data = Menu_GetData(item);
        if (!data) return;
        __disappearAfter = data.disappearAfter;
        Menu_Expand(node, data.horizontalOffset, data.verticalOffset);
    } 
    

    然后我在 AJAX 中抢购由菜单触发的 onclick 回发事件。必须这样做才能取消 onclick 回发并改为显示菜单弹出。

    // Get the Page Request Manager that provides all the .NET 
    var prm = Sys.WebForms.PageRequestManager.getInstance(); 
    // Register postback event for asyncronous AJAX postbacks
    if (prm) prm.add_initializeRequest(InitializePostback);
    function InitializePostback(sender, args) {
      var element = args.get_postBackElement();
      //Check if the postback element is the menu
      if (element.id == 'myMenu') {
        // Name of the menu element that triggered is the postback argument
        var postbackArguments = document.getElementById('__EVENTARGUMENT');
        if (postbackArguments) 
          // Check on the menu item name to pick up only the menu items that shall
          // trigger the popout (not the items that does an actual command).
          if (postbackArguments.value == 'MenuTopItem1' 
           || postbackArguments.value == 'MenuTopItem2'
           || postbackArguments.value == 'MenuTopItem3') {
          // Abort and cancel the postback
          prm.abortPostBack(); 
          args.set_cancel(true);
          Menu_ClickStatic(); // Call my own copy of the original function
          return;
        }
      }
    }
    

    注意:
    我通过使用 Firebug 中的脚本查看器了解了这些函数的详细信息。

    【讨论】:

    • 我使用 vs2013 asp.net 菜单控件,它的 javascript 与上面的代码不同。像这样 >>> hover: function(hovering) { if (hovering) { var currentHoveredItem = this.container.hoveredMenuItem; if (currentHoveredItem) { currentHoveredItem.hover(false); }...........
    • 这就是这样的黑客行为。它不能保证在较新版本的控件中工作......恐怕你需要找到自己的黑客。
    【解决方案2】:

    上面提供的解决方案不适用于任何人。也可以尝试一下,它在我的解决方案中有效-

    var jq = jQuery.noConflict();
                jq(document).ready(function () {
                    jq(document).on('click', '#ctl_id_Here', function () {
                        Menu_HoverStatic(this);
                        Menu_HoverRoot(this);
                    });
                    jq(document).on('click', '#ctl_id_Here', function () {
                        Menu_HoverStatic(this);
                        Menu_HoverRoot(this);
                    });
                }); 
    

    【讨论】:

    • 嗯,这个问题实际上是关于如何利用旧的 ASP.NET Ajax 控件库中的现有事件。当时我没有使用 jQuery,因此引入 jQuery 来破解一个不同的旧时框架是不自然的。如果我现在这样做,我可能会使用 jQuery Ajax 方法而不是使用 ASP.Net ajax 控件库。
    【解决方案3】:

    3 个步骤:

    1. 停止当前的悬停效果:

    在页面加载(或准备就绪)时,编写以下行:$('#Menu1').find('ul .level2').css('display','none');

    一旦您这样做,它将停止该菜单的悬停效果。但是一旦你这样做了,那么你只能通过使其显示块来打开子菜单,所以我写了以下几行,点击菜单内的图像: $('#Menu1').find('ul .level2').css('display','block');

    1. 点击元素打开菜单:我认为不需要解释。只需单击已识别的元素即可制作菜单显示块。

    2. 关闭打开的菜单:两种方法:第一;使用属性 Disapperafter 如下:

    第二:编写下面的代码,点击屏幕上其他任何地方时关闭它:

    $('body').click(function(evnt) {

            if($(evnt.target).parents('table#menu').length == 0) 
            {
                $('#MenuInvitePatient').find('ul .level2').css('display','none');
                    return; 
            }
            else
            {
                    return; 
            }
        }); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-11
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      • 2023-01-15
      相关资源
      最近更新 更多