是否可以强制菜单弹出窗口触发点击而不是鼠标悬停?

时间:2010-12-10 11:17:14

标签: asp.net menu webforms

我使用带有Orientation = Horizo​​ntal的ASP.NET Menu控件。弹出菜单出现在鼠标悬停时有点令人恼火,如果您想要单击菜单下方的某些内容,将鼠标移到菜单上会导致它显示出来。然后菜单弹出窗口隐藏了您实际想要点击的元素!

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

3 个答案:

答案 0 :(得分:3)

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

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

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中使用脚本查看器找到了有关这些函数的详细信息。

答案 1 :(得分:0)

上面提供的解决方案在任何情况下都不起作用。人们也可以试试这个,它在我的解决方案中起作用 -

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

答案 2 :(得分:0)

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