Is it possible to force a menu popout to trigger on click instead of mouseover?

走远了吗. 提交于 2020-06-29 13:10:40

问题


I use a ASP.NET Menu control with Orientation=Horizontal. It is kind of irritating that the popout menus appear on mouseover, which causes it to show by accident if you move the mouse over the menu when you want to click on something right below the menu. Then the menu popout hides the element you actually wanted to click on!

Is it possible to change the functionality so that the popout requires a mouse click instead of mouseover?


回答1:


Well, I found a solution myself (kind of a hack...).
This solution requires use of AJAX to capture the menu item onclick postback event, so it can be picked up client side in javascript before doing the actual postback when you click the menu item.

First, I override these functions that is defined by the Menu control to ignore the menu popout in the mouseover event:

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

Then I snap up the onclick postback event in AJAX that is triggered by the menu. This must be done to cancel the onclick postback and display the menu popout instead.

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

Note:
I found out the details about these functions by using the script viewer in Firebug.




回答2:


The soluton provided above doesn't work in everone's case. One can also try this out, it worked in my solution-

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



回答3:


3 Steps:

  1. Stop the current hovering effects:

On page load (or on ready), write following line: $('#Menu1').find('ul .level2').css('display','none');

Once you do that, it'll stop the hovering effect of that menu. But once you do that, then you would only be able to open the submenu by making it display block, so for that I wrote following lines, onclick of an image inside the menu: $('#Menu1').find('ul .level2').css('display','block');

  1. Open the menu on click of an element: I don't think need to explain it. Just make menu display block on click of the identified element.

  2. Close the opened menu: 2 ways to do it: First; Use property Disapperafter as below:

Second: Write below code to close it onclick of anywhere else on the screen:

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

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


来源:https://stackoverflow.com/questions/4408250/is-it-possible-to-force-a-menu-popout-to-trigger-on-click-instead-of-mouseover

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!