ife系列之自定义鼠标右键菜单
2017-03-02 20:34
204 查看
ife系列之自定义鼠标右键菜单
问题引出:日常浏览网页时,鼠标右键的菜单栏不可缺少,但在有些项目中需要取消浏览器默认的右键菜单,在指定的区域可以自定义右键菜单栏,来满足实际的需要。今天就探讨一下,关于自定义鼠标右键菜单栏的事情。
就目前来说,要实现自定义鼠标右键菜单栏,以下的几个地方需要着重思考一下:
1)如何禁用浏览器默认的右键菜单(受浏览器差异影响);
2)如何触发鼠标右键的点击事件(受浏览器差异影响);
3)如何将自定义的菜单显示出来;
4)如何计算显示在指定区域;
那么,在讲这几个问题之前先说一下,一般浏览器的事件获取机制?(分别在Chrome 55.0.2883.87 (64-bit)、Firefox 50.1.0、IE8环境下测试,下面简称为chrome、Firefox、ie)
1.在chrome下既可以通过参数传递获取事件(显式传递的第一个参数),也可以直接获得全局事件对象window.event
2.在Firefox下只可以通过参数传递获取事件(显式传递的第一个参数)
3.在ie下是直接获取全局事件对象window.event
4.综合上述,我们通常这样写
e = e || window.event;
下面就结合这几个问题来展开:
1)首先第一个问题:如何禁用浏览器默认的右键菜单(受浏览器差异影响)?
答:要想取消浏览器默认的右键菜单,可以使用
e.returnValue = false(其实return false也是可以的,但不是用这种方式)或
e.preventDefault()来阻止默认事件的发生,但是需要考虑兼容性的问题,所以我们可以这么来写
e.preventDefault ? e.preventDefault() : e.returnValue = false;见下图:
2)继续第二个问题:如何触发鼠标右键的点击事件(受浏览器差异影响)?
关于事件的触发,实现的方式也受浏览器差异的影响,最折中的方式是使用事件函数绑定的方式来做兼容性处理(但是楼主没有测试环境,需要ie8以下版本的浏览器,这里就不测试了,只用onXXX的方式),见下图:
算了,还是讲一下兼容性的处理方式,见下图:
3)然后第三个问题:如何将自定义的菜单显示出来?
由于使用
display:none;的方式会导致该元素不参与页面的渲染,这样就无法获取自定义菜单的宽、高,其实首次加载预先保存元素的宽、高也可以,但采用
visibility:hidden;也是可以的,相对来说,既简单又好理解。见下图:
4)最后第四个问题:如何计算显示在指定区域?
这个问题关键就是逻辑,你要保证自定义菜单永远显示在指定区域,而不能超越边界,因此,我这样定义显示的逻辑:
好了,上面是几个关键步骤的讲解,下面上完整代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>自定义网页右键菜单</title> <style type="text/css"> /*去除默认边界*/ div, ul{ margin: 0; padding: 0; } /*去除列表默认样式*/ ul, li{ list-style: none; } /*Start div*/ .div{ position: relative; width: 800px; height: 400px; /*overflow: hidden;*/ } /*Start dv1*/ .dv1{ width: 800px; height: 400px; background: #F5F5F5; border: 1px solid #CCC; border-radius: 5px; text-align: center; line-height: 402px; font-size: 26px; z-index: 1; } /*End dv1*/ /*Start dv2*/ .dv2{ position: absolute;/*相对于父级元素,实现绝对定位*/ width: 200px; height: 100px; color: #F16B41; border: 1px solid #000; border-radius: 5px; visibility: hidden;/*使用visibility控制元素的显隐*/ z-index: 999; background: #FFF; } .dv2 > li{ width: 100%; height: 50px; line-height: 50px; text-align: center; font-size: 16px; } .dv2 > li:hover{ background: #F16B41; cursor: pointer; color: #FFF; } .dv2 > li:nth-child(1){ border-top-left-radius: 5px; border-top-right-radius: 5px; } .dv2 > li:nth-child(2){ border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } /*End dv2*/ /*End div*/ </style> </head> <body> <div class="div"> <!--右键点击有效区域--> <div class="dv1" id="dv1"> <label>Right click to see menu</label> </div> <!--自定义右键菜单栏--> <ul class="dv2" id="dv2"> <li>Menu Item1</li> <li>Menu Item2</li> </ul> </div> <!--javascript代码--> <script type="text/javascript"> window.onload = function(){ var div = document.getElementById("dv1"); var contextMenu = document.getElementById("dv2"); //用户点击右键时,计算显示位置后将右键自定义菜单显示 div.oncontextmenu = function(e){//获取点击坐标事件源 e = e || window.event; // console.log("坐标:(" + e.offsetX + "," + e.offsetY + ")"); var result = calMenuPosition(e.offsetX, e.offsetY);//计算显示位置 contextMenu.style.left = result.left + "px";//别忘了加上"px",^_^ contextMenu.style.top = result.top + "px"; contextMenu.style.visibility = 'visible';//显示 e.preventDefault ? e.preventDefault() : e.returnValue = false; } //用户点击左键时,将右键自定义菜单隐藏 div.onclick = function(e){ e = e || window.event; contextMenu.style.visibility = 'hidden';//隐藏 e.stopPropagation();//解决方式:在子元素触发的事件中,取消事件冒泡(此写法只适用于Firefox和chrome等浏览器) e.cancelBubble = true;//兼容IE,取消事件冒泡 } //全局取消右键的默认操作 document.oncontextmenu = function(e){ e = e || window.event;//兼容IE8、FireFox、chrome e.preventDefault ? e.preventDefault() : e.returnValue = false;//三目运算符进行兼容性判断 } } /** * @function 计算自定义右键菜单栏的显示位置 * @describe 实现逻辑如下: * 假设高度足够,若宽度足够,显示在右下方 * 若宽度不够,显示在左下方 * 假设高度不够,若宽度足够,显示在右上方 * 若宽度不够,显示在左上方 * * @param x 右键点击时x轴坐标 * @param y 右键点击时y轴坐标 * @return left 计算后left的值 * top 计算后top的值 */ function calMenuPosition(x, y){ var div = document.getElementById("dv1"); var div_width = div.clientWidth || div.offsetWidth - 2;//右键有效区域宽度 var div_height = div.clientHeight || div.offsetHeight - 2;//右键有效区域高度 var contextMenu = document.getElementById("dv2"); var con_width = contextMenu.clientWidth || contextMenu.offsetWidth - 2;//自定义菜单栏的宽度 var con_height = contextMenu.clientHeight || contextMenu.offsetHeight - 2;//自定义菜单栏的高度 var conX = 0, conY = 0;//待计算设置坐标 //进行逻辑判断 if(y + con_height <= div_height){//高度足够 if(x + con_width <= div_width){//宽度足够 conX = x; conY = y; }else{//宽度不够 conX = x - con_width; conY = y; } }else{//高度不够 if(x + con_width <= div_width){//宽度足够 conX = x; conY = y - con_height; }else{//宽度不够 conX = x - con_width; conY = y - con_height; } } //返回计算结果 return{ 'left' : conX, 'top' : conY } } </script> </body> </html>
以上便是完整的代码,关于此篇文章的学习笔记和其他代码还可以参见楼主的github地址,ok,有问题的小伙伴,可以留言交流,周末愉快^_^!!!
相关文章推荐
- Silverlight实用窍门系列:4.Silverlight 4.0添加鼠标右键菜单和Silverlight全屏模式的进入退出。【附带源码实例】
- silverlight2自定义鼠标右键菜单,屏蔽原来右键菜单显示的内容,打造自己喜欢的菜单。
- jQuery 自定义鼠标右键菜单
- javascript鼠标右键菜单自定义效果
- svg鼠标右键菜单自定义
- Win7如何自定义鼠标右键菜单 添加新建PowerPoint文档
- js自定义鼠标右键菜单
- jQuery自定义Web页面鼠标右键菜单
- javascript鼠标右键菜单自定义效果
- Silverlight实用窍门系列:4.Silverlight 4.0添加鼠标右键菜单和Silverlight全屏模式的进入退出。【附带源码实例】
- js实现鼠标右键自定义菜单(弹出层),并与树形菜单(TreeView)、iframe合用(兼容IE、Firefox、Chrome)
- 使用Javascript封装实现屏蔽鼠标右键系统键菜单,并绑定自定义的事件
- 简单的自定义鼠标右键菜单
- 阻止右键菜单(阻止默认事件)&&跟随鼠标移动(大图展示)&&自定义右键菜单
- Flex屏蔽并自定义鼠标右键菜单(转载)
- Flex屏蔽并自定义鼠标右键菜单(转载)
- Flex屏蔽并自定义鼠标右键菜单
- 自定义鼠标右键(层叠式菜单:cascading menu)(文件系统右键、文件夹系统右键和桌面鼠标右键)
- js实现完全自定义可带多级目录的网页鼠标右键菜单方法
- 鼠标右键自定义菜单