自定义右键菜单
技术一般水平有限,有什么错的地方,望大家指正。
自定义右键菜单,对于一些ERP系统,功能操作比较多,所以我们通常把常用的几个功能放在自定义的右键菜单里方便用户使用。
实现自定义菜单很简单,首先我们要屏蔽原始的右键菜单,自定义菜单出现在鼠标的位置,点击隐藏自定义菜单,过程就是这样的。
*{margin:0;padding:0} a{text-decoration:none} ul li{list-style:none} .menu{border:1px solid black;border-radius:5px;display:inline-block;position:fixed;top:100px;left:550px;
overflow:hidden;padding-bottom:10px;box-shadow:0 0 10px 0;z-index:999;display:none;background:white} .menu ul li{height:30px;100%} .menu ul li a{height:30px;display:inline-block;100%;text-align:left;line-height:30px;padding:5px 10px} .menu li a:hover{background-color:#EEF5E2}
<div class="menu" id="demo"> <ul> <li><a href="#">向录入员发送消息</a></li> <li><a href="#">发送选中作业</a></li> <li><a href="#">设置作业状态</a></li> <li><a href="#">哈哈哈哈哈</a></li> <li><a href="#">嘻嘻嘻嘻嘻</a></li> <li><a href="#">呵呵呵呵呵呵</a></li> </ul> </div>
1.屏蔽原始的右键菜单
在JS中提供了一个事件来完成这件事就是oncontextmenu,这个是事件绑定的区域在点击右键时将不会再出现原始右键菜单:
document.oncontextmenu = function(){ return false; }
2.获取自定义菜单的大小
自定义菜单初始是隐藏的,对于隐藏的元素我们是没有办法来获取它的宽高的。我们可以先将菜单元素设置为visibility:hidden,获取到元素的宽高后在去掉这个属性:
function getHideDOMWH(obj){ //obj为菜单元素的DOM对象 var wh = {}; obj.style.visibility = "hidden"; wh.w = obj.scrollWidth; wh.h = obj.scrollHeight; obj.style.visibility = null; return wh; }
3.自定义菜单出现在当前鼠标的位置
首先我们就需要获取当前的鼠标的位置,当前鼠标位置就是自定义菜单出现的位置。同时要注意距右侧距离或者距下面的距离不足以显示菜单的情况:
document.onmousedown = function(e){ //obj为菜单元素DOM对象 var e = e || window.event; if(e.button==2){ var left = e.clientX; var top = e.clientY; var windowHeight = document.body.scrollHeight; var windowWidth = document.body.scrollWidth; var wh = getHideDOMWH(obj); var contentHeight = wh.h; var contentWidth = wh.w; obj.style.left = windowWidth-left>contentWidth?left+"px":windowWidth-contentWidth+"px"; obj.style.top = windowHeight-top>contentHeight?top+"px":top-contentHeight+"px"; obj.style.display = "inline-block"; } }
当浏览器窗口的宽度减去光标点击时距离左边的距离小于菜单的宽度的时候,说明光标距离右边的距离已经不足以显示菜单了,我们就让菜单的紧贴右侧,此时菜单的left值为浏览器窗口的宽度减去菜单的宽度。当浏览器窗口的高度减去光标距离上侧的距离小于菜单的高度时,说明此时光标距离下面的距离不足以显示菜单了,此时菜单的top值为光标距离上面的距离减去菜单的高度。
4.无论是点击菜单元素还是其他元素都隐藏菜单
document.onclick = function(){ //obj为菜单元素DOM对象 obj.style.display = "none"; }
为了使用方便我们可以将上面的这个过程封装成一个方法,或者在原生JS的Element的原型上扩展一个方法(IE7及以下是会报错的),或者是JQ的原型上,这里我们封装一个方法。
function contextMenu(obj){ //obj为DOM对象 document.oncontextmenu = function(){ return false; } document.onmousedown = function(e){ var e = e||window.event; if(e.button==2){ var mouseX = e.clientX; var mouseY = e.clientY; var wh = getObjWH(obj); var contentW = wh.w; var contentH = wh.h; var documentW = document.body.scrollWidth; var documentH = document.body.scrollHeight; obj.style.left = documentW-mouseX<contentW?documentW-contentW+"px":mouseX+"px"; obj.style.top = documentH-mouseY<contentH?mouseY-contentH+"px":mouseY+"px"; obj.style.display = "inline-block"; } } document.onclick = function(){ obj.style.display = "none"; } function getObjWH(obj){ var wh = {}; obj.style.visibility = "hidden"; wh.w = obj.scrollWidth; wh.h = obj.scrollHeight; obj.style.visibility = null; return wh; } }
我们所有的事件都是绑定在document上的而事件我们通常会使用冒泡机制,如果我们在某个元素上设置了取消冒泡则会有一些问题,我们需要做一些针对性的处理。