自定义右键菜单项

简介: 摘要:   我们经常在网上能够看到点击鼠标右键弹出自定义的菜单项,自定义菜单可以使菜单项的样式和网站主题相似,开发自己需要的功能。​本文分享了自己制作的右键菜单项,其主要特点是,当菜单项超出浏览器的可视区域时,改变菜单项的显示位置。

摘要:

  我们经常在网上能够看到点击鼠标右键弹出自定义的菜单项,自定义菜单可以使菜单项的样式和网站主题相似,开发自己需要的功能。​本文分享了自己制作的右键菜单项,其主要特点是,当菜单项超出浏览器的可视区域时,改变菜单项的显示位置。

/*技术难点*/

1、获取文本的高度和宽度

使用window.getComputedStyle()方法获取的是auto值,并不是具体的值,无法实现当超出可视区域换方向

解决方法:

 计算每一个li元素的高度和宽度,最终宽度取最大宽度,高度是每个li元素的高度之和加上边距

2、获取浏览器可视区域的高度

使用document.body.clientHeight获取的值为0,因为页面没有内容,理所当然高度为0

解决方法:

 使用document.documentElement.clientHeight来计算浏览器的可视区域高度

DEMO:

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5 <title>ContextMenu</title>
  6 <style>
  7 #contextMenu {border:1px solid rgb(219,219,219); position:absolute;margin:5px;padding: 0;}
  8 #contextMenu li{list-style:none;margin-bottom: 5px;cursor:pointer;background-color: rgb(255, 174, 0);border-bottom: 1px solid #fff;}
  9 </style>
 10 </head>
 11 <body>
 12 <script>
 13 // 菜单列表
 14 var menuList = [
 15     {
 16         'text': '刷新',
 17         'id': 'one'
 18     },{
 19         'text': '复制',
 20         'id': 'two'
 21     },{
 22         'text': '剪切',
 23         'id': 'three'
 24     },{
 25         'text': '重新加载',
 26         'id': 'four'
 27     }
 28 ];
 29 // 获取菜单的宽和高
 30 function getStyle(list) {
 31     var wid = 0,hei = 0;
 32     for(var i = 0, l = list.length; i < l; i++) {
 33         var res = textSize(list[i].text);
 34         if(res.width > wid) {
 35             wid = res.width
 36         }
 37         hei += res.height;
 38     }
 39     // 加上间距
 40     hei += i*5+20;
 41     wid += 10;
 42     return {
 43         wid: wid,
 44         hei: hei
 45     };
 46 }
 47 // 右键点击显示菜单项
 48 document.oncontextmenu=function(ev){
 49     // 如果菜单项已经存在了,则删除
 50     var ctx=document.getElementById('contextMenu');
 51     if(ctx) {
 52         ctx.parentNode.removeChild(ctx);
 53     }
 54     var menu = document.createElement('ul');
 55     menu.id = 'contextMenu';
 56     menu.style.display = 'none';
 57     for(var i = 0, l = menuList.length; i < l; i++) {
 58         var list=document.createElement("li");
 59         list.id = menuList[i].id;
 60         var node=document.createTextNode(menuList[i].text);
 61         list.appendChild(node);
 62         menu.appendChild(list);
 63     }
 64     document.getElementsByTagName('body')[0].appendChild(menu);
 65     var
 66     l,t,
 67     eve = ev||event,
 68     sty = getStyle(menuList),
 69     wid = parseInt(sty.wid),
 70     hei = parseInt(sty.hei);
 71     l = eve.clientX+wid>document.body.offsetWidth ? eve.clientX - wid : eve.clientX;
 72     t = eve.clientY+hei>document.documentElement.clientHeight ? eve.clientY - hei : eve.clientY;
 73     menu.style.left    = l+'px';    
 74     menu.style.top     = t+'px';
 75     menu.style.display = 'block';
 76     return false;
 77 }
 78 // 当点击页面时,删除菜单项
 79 window.onclick=function (event)
 80 {
 81     var ctx=document.getElementById('contextMenu');
 82     if(ctx) {
 83         if(event.target.parentNode.id === 'contextMenu') {
 84             ctx.style.display = 'none';
 85             alert('你点击了'+event.target.innerText);
 86         };
 87         ctx.parentNode.removeChild(ctx);
 88     }
 89 };
 90 function textSize(text) {
 91     //计算一段文本的真实长度和高度
 92     var span = document.createElement("span");
 93     var result    = {};
 94     result.width  = span.offsetWidth;
 95     result.height = span.offsetHeight;
 96     span.style.visibility = "hidden";
 97     document.getElementsByTagName('body')[0].appendChild(span);
 98     if(typeof span.textContent !== "undefined"){
 99         span.textContent = text;
100     } else {
101         span.innerText = text
102     }
103     result.width  = span.offsetWidth - result.width;
104     result.height = span.offsetHeight - result.height;
105     span.parentNode.removeChild(span);
106     return result;
107 }
108 </script>
109 </body>
110 </html>

 

相关文章
|
存储 安全 Java
从源码角度来谈谈 HashMap
HashMap的知识点可以说在面试中经常被问到,是Java中比较常见的一种数据结构。所以这一篇就通过源码来深入理解下HashMap。
151 0
从源码角度来谈谈 HashMap
|
存储 边缘计算 人工智能
【边缘计算与AI】分析边缘计算在处理AI任务、优化响应速度和数据隐私保护方面的作用和潜力
边缘计算与AI的结合是当前技术发展的重要趋势,两者相互依存、相互促进,共同推动着数字化转型的深入发展。以下是对边缘计算与AI关系的详细分析
398 6
|
安全 API 数据安全/隐私保护
史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(一)
欢迎访问我的原站!本文详细介绍了程序脱壳技术,包括壳的定义、作用、执行过程、OEP(原始入口点)的概念及查找方法。文章通过多个实例,逐步演示了如何使用OD(OllyDbg)等工具进行脱壳操作,涵盖了压缩壳、加密壳等多种类型的壳。内容详尽,适合逆向工程初学者深入学习。[点击查看原文](https://www.oisec.cn/index.php/archives/520/)
1398 1
|
人工智能 搜索推荐 安全
移动应用与系统的发展与挑战
移动应用与系统的发展不仅改变了人们的生活方式,也给技术行业带来了巨大的影响。本文将探讨移动应用开发和移动操作系统等相关话题,分析当前行业的发展趋势和面临的挑战,同时展望未来的发展方向。
134 3
|
XML API 数据格式
微信PC版的API接口
微信PC版的API接口
1021 0
|
前端开发 JavaScript Go
webpack -vite(Rollup )-Gulp (一)
webpack -vite(Rollup )-Gulp (一)
267 0
java实现(燃油车车牌生成)
java实现(燃油车车牌生成)
|
缓存 前端开发 安全
预检请求:为跨域请求保驾护航(下)
预检请求:为跨域请求保驾护航(下)
|
Linux 编译器 KVM
Alibaba Cloud Linux操作系统的安装及使用
Linux操作系统的安装,体会操作系统为了方便用户,不断改进的安装过程;熟悉Linux系统的登录和退出,并熟悉它常用命令的操作使用方法。
|
存储 编译器 C语言
02-结构体和OC类的内存对齐
02-结构体和OC类的内存对齐
144 0
下一篇
oss云网关配置