jquery右键菜单扩展,支持多级菜单

天远科技  发表于:2022-05-23  分类:HTML/JS/CSS相关  阅读(2164)  赞同34

最近接了个项目甲方爸爸一定要操作像桌面系统一样,要有邮件菜单,由于我们的系统用了动态生成tab,每个tab动态绑定菜单太麻烦了,故重新造了个轮子,有需要的同学直接拿走。

菜单有2个特殊的方法,一个用于通过target去区分是否要拦截的onInit,我这边主要用于是否弹出菜单,因为我在动态加载的上层绑定了菜单,另一个用于菜单项目重构的setMenu方法.


使用:

1、引入下方css

@charset "UTF-8";
#TYF_contextmenu {position: absolute;z-index:9996;}
#TYF_contextmenu .cm_default {background:#ccc;margin: 0;padding: 3px 0;list-style:none;cursor: pointer;box-sizing: border-box;min-width:88px;font-size:14px;border:1px solid #ccc;}
#TYF_contextmenu a {display: block;text-decoration: none;}
#TYF_contextmenu a.disabled {cursor: not-allowed;color: gray;}
#TYF_contextmenu .cm_default li {padding-left:5px;position: relative;}
#TYF_contextmenu .cm_default>li:not(:last-child) {border-bottom:1px solid #ccc;}
#TYF_contextmenu .cm_default li img {width:16px;height:16px;display: inline-block;vertical-align: middle;margin-right:2px;}
#TYF_contextmenu .cm_radius {border-radius:5px;}
#TYF_contextmenu .cm_shadow {box-shadow:darkgrey 0 0 10px 0;}
#TYF_contextmenu li .cm_icon {padding-left:18px;}
#TYF_contextmenu .cm_default li s {width:6px;height:6px;border:1px solid #888;border-left-width:0;border-bottom-width:0;display:block;position:absolute;right:8px;transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);}
#TYF_contextmenu .cm_sub {position: absolute;top:0px;z-index:9997;display:none;}

2、js源码

(function($) {
var menu;
var menucss = {};
var options = {};
var _defaultOptions = {
width:110, //菜单宽度
height:26, //菜单项高度
color:'#000000', //默认字体颜色
arrowcolor:'#888888', //下级菜单箭头颜色
fontsize:14, //字体大小,单位像素
menuColor:'#ffffff', //菜单背景色
boardColor:'#aaaaaa', //菜单边框颜色
itemColor:'#eeeeee', //菜单选中项背景色
fontColor:'#000000', //菜单选中项字体颜色
lineColor:'#dddddd', //分隔线颜色,分隔线颜色和背景色相同则看不出分割线
isRadius:false, //是否圆角
isShadow:true, //是否显示菜单阴影
isIcon:false, //显示图标,该项为false则配置icon也不显示
onInit:null, //前置过滤函数,参数e为右键target对象,返回布尔值,用于右键点击某个target是否显示,eg: onInit:function(e) { ... return true}
setMenu:null, //通过该函数可根据target的动态菜单,参数e为右键target对象,返回菜单对象,菜单对象同item,eg: setMenu:function(e) {... return menu}
item:[], //静态菜单项eg:item[{text:关闭,icon:"/images/color.png",disable:true,click:function(target){}}],文字,图标,是否禁用默认false,点击后的效果其中target为目标对象
}
$.fn.contextMenu = function(options) {
if(!menu) {
options = object.assign(_defaultOptions,options);
menu = init(options);
$(document).bind("click",function(){
menu.hide();
});
}
$(this).bind("contextmenu",function(e) {
var _hasMenu = (!!options.onInit) ? options.onInit(e.target) : true;
if(_hasMenu) show(e,options);
return false;
});
return this;
}
init=function(options) {
menucss = {width:options.width,backgroundColor:options.menuColor,borderColor:options.boardColor}
var _menustr = '<div id="TYF_contextmenu"><ul class="cm_default';
if(options.isRadius) _menustr += ' cm_radius';
if(options.isShadow) _menustr += ' cm_shadow';
_menustr += '">';
_menustr += '</ul></div>';
var _menuObj = $(_menustr).hide().appendTo('body').bind('click',function(e){
e.stopPropagation();
});
_menuObj.children('ul').css(menucss);
return _menuObj;
}
setItem = function(item,target,options) {
var _menustr = '<li>';
_menustr += '<a href="javascript:void(0);"';
if(_disable) _menustr += ' class="disabled"';
_menustr += '>';
var _disable = !!item.disable ? item.disable : false;
if(options.isIcon) {
_menustr += !!item.icon ? '<img src="'+item.icon+'" />' : '<span class="cm_icon"></span>';
}

_menustr += item.text + '</a>';
if(!!item.sub) {
_menustr += '<s';
_menustr += ' style="border-color:'+options.arrowcolor+';top:'+(options.height/2-4.2)+'px"';
_menustr += '></s><ul class="cm_default cm_sub';
if(options.isRadius) _menustr += ' cm_radius';
if(options.isShadow) _menustr += ' cm_shadow';
_menustr += '"></ul>';
}
_menustr += '</li>';
var _menuItemObj = $(_menustr).css({borderColor:options.lineColor,height:options.height,lineHeight:options.height+'px'});
_menuItemObj.children('a').css({color:options.color}).bind('click',function(){
item.click(target);
});
menucss.left = options.width-10;
_menuItemObj.children("ul").css(menucss);
if(!_disable) {
_menuItemObj.hover(
function() {
$(this).css({backgroundColor:options.itemColor,color:options.fontColor});
$(this).children('ul').show();
},
function() {
$(this).css({backgroundColor:options.menuColor,color:options.color});
$(this).children('ul').hide();
}
);
}
if(!!item.sub) {
var _subItme = null;
$.each(item.sub,function(k,v){
_subItme = setItem(v,target,options);
_menuItemObj.children('ul').append(_subItme);
});
}
_menuItemObj.bind('click',function(){
menu.hide();
});
return _menuItemObj;
}
show = function(obj,options) {
if(!!options.setMenu) options.item = options.setMenu(obj.target);
menu.css({'left':obj.pageX,'top':obj.pageY}).show();
var _menustr,_menuObj;
menu.children("ul").empty();
if(!!options.item) {
$.each(options.item,function(k,v){
var _menuItem = setItem(v,obj.target,options);
menu.children('ul').append(_menuItem);
});
}
}
})(jQuery);

3、参数说明,传入一个option对象,参数如下

width:110, //菜单宽度
height:26, //菜单项高度
color:'#000000', //默认字体颜色
arrowcolor:'#888888', //下级菜单箭头颜色
fontsize:14, //字体大小,单位像素
menuColor:'#ffffff', //菜单背景色
boardColor:'#aaaaaa', //菜单边框颜色
itemColor:'#eeeeee', //菜单选中项背景色
fontColor:'#000000', //菜单选中项字体颜色
lineColor:'#dddddd', //分隔线颜色,分隔线颜色和背景色相同则看不出分割线
isRadius:false, //是否圆角
isShadow:true, //是否显示菜单阴影
isIcon:false, //显示图标,该项为false则配置icon也不显示
onInit:null, //前置过滤函数,参数e为右键target对象,返回布尔值,用于右键点击某个target是否显示,eg: onInit:function(e) { ... return true}
setMenu:null, //通过该函数可根据target的动态菜单,参数e为右键target对象,返回菜单对象,菜单对象同item,eg: setMenu:function(e) {... return menu}
item:[], //静态菜单项eg:item[{text:关闭,icon:"/images/color.png",disable:true,click:function(target){}}],文字,图标,是否禁用默认false,点击后的效果其中target为目标对象


4、示例

$('.TYF_body .tabscontent').contextMenu({
    isRadius:true,
    lineColor:'#fff',
    item:[
      {
        text:'关闭当前菜单',
        icon:'/images/tjf/delete.png',
        click:function(target) {
          console.log(target);
          alert('aaa');
        }
      },
      {
        text:'关闭右侧菜单',
        click:function(target) {
          console.log(target);
          alert('bbb');
        },
        sub:[
          {
            text:'子菜单1',
            click:function(target) {
              console.log(target);
              alert('sub1');
            },
            sub:[
              {
                text:'aaaa',
                click:function(target) {
                  alert('hhh');
                }
              }
            ]
          },
          {
            text:'子菜单2',
            click:function(target) {
              console.log(target);
              alert('sub2');
            }
          }
        ]
      },
      {
        text:'关闭左侧菜单',
        disable:true,
        click:function(target) {
          console.log(target);
          alert('ccc');
        }
      },
      {
        text:'关闭其他菜单',
        click:function(target) {
          console.log(target);
          alert('ddd');
        }
      }
    ],
    onInit:function(e) {
      if(!!$(e).attr('data')) return true;
      return false;
    },
    setMenu:function(e) {
      console.log(e);
      if(!!$(e).attr('data') && $(e).attr('data')==10) {
        return [
          {
            text:'新菜单',
            click:function(target) {
              alert('new menu');
            }
          }
        ];
      }else{
        return [
          {
            text:'关闭当前菜单',
            icon:'/images/tjf/delete.png',
            click:function(target) {
              console.log(target);
              alert('aaa');
            }
          },
          {
            text:'关闭右侧菜单',
            click:function(target) {
              console.log(target);
              alert('bbb');
            },
            sub:[
              {
                text:'子菜单1',
                click:function(target) {
                  console.log(target);
                  alert('sub1');
                },
                sub:[
                  {
                    text:'aaaa',
                    click:function(target) {
                      alert('hhh');
                    }
                  }
                ]
              },
              {
                text:'子菜单2',
                click:function(target) {
                  console.log(target);
                  alert('sub2');
                }
              }
            ]
          },
          {
            text:'关闭左侧菜单',
            disable:true,
            click:function(target) {
              console.log(target);
              alert('ccc');
            }
          },
          {
            text:'关闭其他菜单',
            click:function(target) {
              console.log(target);
              alert('ddd');
            }
          }
        ];
      }
    }
  });

博文分类

线

在线联系
点击这里给我发消息
点击这里给我发消息
关注我们