jQuery Make left invoke Right Click Context Menu

2019-08-07 15:56发布

I am using some functionality I found over here: http://www.trendskitchens.co.nz/jquery/contextmenu/

It gets me started making a nice Context Menu. My purpose was to get this context menu to "Pop" on right OR left click. But I might not ALWAYS want to bind the left click, so I need to be able to always do right click, and when I want, make the left click work too with a bit of code.

First, to test you will need jQuery for the demo, I am using 1.8.2

Here is the source of the plugin:

/*
 * ContextMenu - jQuery plugin for right-click context menus
 *
 * Author: Chris Domigan
 * Contributors: Dan G. Switzer, II
 * Parts of this plugin are inspired by Joern Zaefferer's Tooltip plugin
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Version: r2
 * Date: 16 July 2007
 *
 * For documentation visit http://www.trendskitchens.co.nz/jquery/contextmenu/
 *
 */

(function($) {

    var menu, shadow, trigger, content, hash, currentTarget;
  var defaults = {
    menuStyle: {
      listStyle: 'none',
      padding: '1px',
      margin: '0px',
      backgroundColor: '#fff',
      border: '1px solid #999',
      width: '100px'
    },
    itemStyle: {
      margin: '0px',
      color: '#000',
      display: 'block',
      cursor: 'default',
      padding: '3px',
      border: '1px solid #fff',
      backgroundColor: 'transparent'
    },
    itemHoverStyle: {
      border: '1px solid #0a246a',
      backgroundColor: '#b6bdd2'
    },
    eventPosX: 'pageX',
    eventPosY: 'pageY',
    shadow : true,
    onContextMenu: null,
    onShowMenu: null
    };

  $.fn.contextMenu = function(id, options) {
    if (!menu) {                                      // Create singleton menu
      menu = $('<div id="jqContextMenu"></div>')
               .hide()
               .css({position:'absolute', zIndex:'500'})
               .appendTo('body')
               .bind('click', function(e) {
                 e.stopPropagation();
               });
    }
    if (!shadow) {
      shadow = $('<div></div>')
                 .css({backgroundColor:'#000',position:'absolute',opacity:0.2,zIndex:499})
                 .appendTo('body')
                 .hide();
    }
    hash = hash || [];
    hash.push({
      id : id,
      menuStyle: $.extend({}, defaults.menuStyle, options.menuStyle || {}),
      itemStyle: $.extend({}, defaults.itemStyle, options.itemStyle || {}),
      itemHoverStyle: $.extend({}, defaults.itemHoverStyle, options.itemHoverStyle || {}),
      bindings: options.bindings || {},
      shadow: options.shadow || options.shadow === false ? options.shadow : defaults.shadow,
      onContextMenu: options.onContextMenu || defaults.onContextMenu,
      onShowMenu: options.onShowMenu || defaults.onShowMenu,
      eventPosX: options.eventPosX || defaults.eventPosX,
      eventPosY: options.eventPosY || defaults.eventPosY
    });

    var index = hash.length - 1;
    $(this).bind('contextmenu', function(e) {
      // Check if onContextMenu() defined
      var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e) : true;
      if (bShowContext) display(index, this, e, options);
      return false;
    });
    return this;
  };

  function display(index, trigger, e, options) {
    var cur = hash[index];
    content = $('#'+cur.id).find('ul:first').clone(true);
    content.css(cur.menuStyle).find('li').css(cur.itemStyle).hover(
      function() {
        $(this).css(cur.itemHoverStyle);
      },
      function(){
        $(this).css(cur.itemStyle);
      }
    ).find('img').css({verticalAlign:'middle',paddingRight:'2px'});

    // Send the content to the menu
    menu.html(content);

    // if there's an onShowMenu, run it now -- must run after content has been added
        // if you try to alter the content variable before the menu.html(), IE6 has issues
        // updating the content
    if (!!cur.onShowMenu) menu = cur.onShowMenu(e, menu);

    $.each(cur.bindings, function(id, func) {
      $('#'+id, menu).bind('click', function(e) {
        hide();
        func(trigger, currentTarget);
      });
    });

    menu.css({'left':e[cur.eventPosX],'top':e[cur.eventPosY]}).show();
    if (cur.shadow) shadow.css({width:menu.width(),height:menu.height(),left:e.pageX+2,top:e.pageY+2}).show();
    $(document).one('click', hide);
  }

  function hide() {
    menu.hide();
    shadow.hide();
  }

  // Apply defaults
  $.contextMenu = {
    defaults : function(userDefaults) {
      $.each(userDefaults, function(i, val) {
        if (typeof val == 'object' && defaults[i]) {
          $.extend(defaults[i], val);
        }
        else defaults[i] = val;
      });
    }
  };

})(jQuery);

$(function() {
  $('div.contextMenu').hide();
});

And the Source of my Page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><!-- InstanceBegin template="/Templates/Workflow.dwt.php" codeOutsideHTMLIsLocked="false" -->
    <head>
        <script type="text/javascript" src="../jQuery/jquery-1.8.2.min.js"></script>
        <script type="text/javascript" src="../../Common/clientscript.js"></script>
        <script type="text/javascript" src="jquery.actions.js"></script>
        <script>
            $(document).ready(function() {
                /// Replace the intrinsic Context Menu with MINE
                $('span.infoholder').contextMenu('myMenu',{
                    onContextMenu: function(e)
                    {
                        iDataID = $(e.target).attr('id').replace("menu_","");
                        iGroupID = $(e.target).attr('name');


                    }
                });

                /// Get the Left Click to behave as the right click...
                $("span.infoholder").click(function(event) {
                    alert("I am in " + event.which);
                    // on right click
                    if (event.which == "1")
                    {
                        // prevent left click from being interpreted by the browser:
                        $("#"+$(event.target).attr("id")).trigger({
                            type: 'click',
                            which: 3
                        });
                    }
                });
            });
        </script>
    </head>
    <body>
    <div class="contextMenu" id="myMenu">
        <li>Test 1</li>
        <li>Test 2</li>
    </div>
    <span class="infoholder" id="menu_34675"     name="1"     style="border:solid 1px grey; padding: 2px 5px 2px 5px; background-color:#d9f7ff;">Actions </span><br/><br/>
    <span class="infoholder" id="menu_34735"     name="1"     style="border:solid 1px grey; padding: 2px 5px 2px 5px; background-color:#d9f7ff;">Actions </span><br/><br/>
    </body>
</html>

There is a bit missing from this, but the source here gives us an good sample to get started on the problem. Which again is "How to get the left click to invoke the custom context menu of this plugin"

2条回答
够拽才男人
2楼-- · 2019-08-07 16:16

Here is the answer, BIND it to the click in the plugin Javascript

$(this).bind('click', function(e) {
    // Check if onContextMenu() defined
    var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e) : true;
    if (bShowContext) display(index, this, e, options);
    return false;
});
查看更多
等我变得足够好
3楼-- · 2019-08-07 16:24

Just add the 'contextmenu to the items binding to:

$(this).bind('click contextmenu', function(e) {
   // Check if onContextMenu() defined
   var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e) : true;
   if (bShowContext) display(index, this, e, options);
   return false;
});
return this;
查看更多
登录 后发表回答