迷你右键菜单

右键菜单使用范围比较小,主要用来开发调试时候使用,网上现成的功能较全体积较大或依赖其他第三方 不便使用,所以自己写了一个。

体积小巧,样式简单,Chrome 与 Edge 下样式有略微区别,跟随 浏览器默认右键菜单样式 当然模仿的不是特别像 🤣。

代码如下

/**
 * 右键菜单
 * 
 * contextmenu(selectors, menus, call = null)
 * selectors css 选择器
 * menus 菜单数组 包含多个菜单项目
 *      单个菜单项目如下,也可以是 如果只有 name 可以简写为 字符串
 *      {
 *          name: '菜单名称', // 必须 如果 - 组成的当做分割线处理
 *          on: (data, context, target) => {}, // 回调事件 可选
 *          data: null,  // 任意类型 附加数据 可选
 *          desc: null,  // 简介 可选
 *          icon: null,  // 图标 可选 https://cdn.asilu.com/material-icons/ 复制 图标 含 “/” 作图片处理
 *          color: null, // 图标颜色 可选
 *      }
 * call 该组菜单的回调事件 参数:(name, data, context, target)
 * 
 * 
 * 20231128 添加 Edge 样式
 * 20231129 添加 menu 方法, 单击菜单
 * 20231130 添加 菜单图标颜色 color 2900
 * 20231216 添加 边界判断 以防超出 可视区域
 */

['contextmenu','menu'].map(t=>{var s=document,e=window,n=t,r='addEventListener',p=(t,e,n)=>{let i=s.createElement(t);return(e instanceof Element?e:s[e||'body']).append(i),n&&i.classList.add(...n.split(/\s+/)),i},l=[],i='contextmenu',d=n+'--'+ +new Date,x=t=>t.preventDefault(),m=(t,e,n=0)=>Math.max(Math.min(t,e-5),n+5),g=(t,e)=>{if(t.target.closest('.'+d))return!0;l.map(t=>{t[1]!=e&&f(t[1],1)})},f=(t,e)=>(!e||!t.classList.contains('x'))&&(t.classList[e?'add':'remove']('x'),e&&t.removeAttribute('style'));e[n]=function(t,e,c){l.length||(s[r]('click',g,!0),s[r](n==i?i:'click',e=>{if(g(e))return x(e);let n=l.map(t=>[e.target.closest(t[0]),t[1]]).filter(t=>t[0]);if(0<n.length){x(e);var i,s=(n=n.sort((t,e)=>t[0].contains(e[0])?1:-1))[0][1].offsetWidth,c=n[0][1].offsetHeight,a=innerWidth,o=innerHeight;let t={top:e.pageY,left:e.pageX};for(i in t.left=m(t.left,a-s),t.top=m(t.top,t.top+o-e.clientY-c),t)n[0][1].style[i]=t[i]+'px';f(n[0][1]),n[0][1].cmc=n[0][0],n[0][1].cm2=e.target}},!0),p('style','head',d+'-style').textContent=`@import url(https://cdn.asilu.com/material-icons.css);.cssn{--r:8px;--py:8px;--i:22px;--b:#f2f2f2;--h:#d3e3fd;top:0;font-family:"Segoe UI",Arial,"Microsoft Yahei",sans-serif;box-shadow:0 4px 10px rgba(0,0,0,.08),0 16px 24px 2px rgba(0,0,0,.04),0 6px 30px 5px rgba(0,0,0,.05);border:0;background-color:#fff;padding-top:var(--py);padding-bottom:var(--py);position:absolute;z-index:98919999;min-width:160px;border-radius:var(--r)}.cssn.x{visibility:hidden;opacity:0}.cssn,.cssn *{box-sizing:border-box}.cssn-item{padding:3px 20px;text-overflow:ellipsis;cursor:pointer;line-height:22px;transition:all .3s}.cssn-item-hr:after{content:"";display:block;height:1px;margin:6px 0;background-color:var(--h)}.cssn-item:hover{background-color:var(--b)}.cssn-item img.cssn-icon{height:18px}.cssn-item .cssn-icon{display:flex;align-items:center;width:var(--i);min-width:var(--i);height:var(--i);text-align:center;font-size:20px;object-fit:contain;overflow:hidden}.cssn-item,.cssn-item .cssn-box{display:flex;align-items:center;gap:10px;width:100%}.cssn-item .cssn-box{justify-content:space-between;gap:30px;color:#333}.cssn-item .cssn-box *{font-size:12px!important}.cssn-item .cssn-desc{min-width:20px;color:#999;text-align:right}.cssn.old{--py:2px;--r:0px}.cssn.old .cssn-item{margin:0 2px;width:calc(100% - 4px);padding:0 20px 0 8px}.cssn.edg{--py:4px;--b:#d3dfe9;--h:#dadada}.cssn.edg .cssn-item{border-radius:3px;margin:2px 4px;width:calc(100% - 8px);padding-left:8px}`.replace(/cssn/g,d));let a=p('div','body',d+' x'),o=(l.push([t,a]),e.filter(t=>t&&t.icon).length);e.map(e=>{'string'==typeof e&&(e={name:e});var n=/^-*$/.test(e.name);let i=p('div',a,d+'-item'+(n?'-hr':''));if(!n){if(o){var n=e.icon||'',s=/\//.test(n)&&!/</.test(n);let t=p(s?'img':'div',i,d+'-icon material-icons');t[s?'src':'innerHTML']=n,e.color&&(t.style.color=e.color)}s=p('div',i,d+'-box');p('div',s,d+'-name').textContent=e.name,p('div',s,d+'-desc').textContent=e.desc||'',i[r]('click',function(){f(a,1),e.on&&e.on.call(a.cmc,e.data||null,a.cmc,a.cm2,e),c&&c.call(a.cmc,e.name,e.data||null,a.cmc,a.cm2,e)})}}),-1<navigator.userAgent.indexOf(' Edg/')&&a.classList.add('edg')}});

体积 3KB 多一点,支持自定义图标以及图标颜色。

右键菜单又称上下文菜单 所以在回调里面可以获取 点击菜单,以及激活显示的元素,或者附加数据等。

 

Chrome 下截图如下

 

具体使用请查看 演示地址

 

Post Author: admin