[技术博客]前端右键菜单的实现

[技术博客]前端右键菜单的实现

TexrMarking项目开发过程中,需要实现右键菜单对实体进行删除、修改功能。

在此我记录下关于右键菜单的实现。

HTML contextmenu 属性

首先我们来介绍Firefox浏览器特有的contextmenu属性。

<div contextmenu="mymenu">

<menu type="context" id="mymenu">
  <menuitem label="Refresh"></menuitem>
  <menuitem label="Twitter"></menuitem>
</menu>

</div>

contextmenu 属性规定了元素的上下文菜单。当用户右击元素时将显示上下文菜单。

contextmenu 属性的值是需要打开的

元素的 id。

但是在具体实现过程中,contextmenu属性并不能很好地适应我们项目的要求。同时,contextmenu属性只适应firefox浏览器,在兼容性上也有很大的问题。总的来说contextmenu不能解决我们的问题。

使用JS制作右键菜单

首先是html的结构

<dir id = "rightmenu" class="rightmenu">
	<ul>
		<li disabled="disabled"><a href="#">返回(B)</a><span>Alt+向左箭头</span></li>
		<li><a href="#">前进(F)</a><span>Alt+向右箭头</span></li>
		<li><a href="#">重新加载(R)</a><span>Ctrl+R</span></li>
	</ul>
	<ul>
		<li><a href="#">另存为(A)...</a><span>Ctrl+5</span></li>
		<li><a href="#">打印(P)...</a><span>Ctrl+P</span></li>
		<li><a href="#">投射(C)...</a><span>Ctrl+R</span></li>
	</ul>
	<ul>
		<li><a href="#">查看代码(V)</a><span>Ctrl+U</span></li>
		<li><a href="#">检查代码(N)</a><span>Ctrl+Shift+L</span></li>
	</ul>
</dir>

这里按照谷歌浏览器默认的右键菜单来进行布局

在写CSS文件时需要注意,.rightmenu设置display:none是因为右键菜单本身是隐藏了因为点击了才出现,倘若不加这句,菜单会出现在页面的左上角

JS实现

<script >
	document.addEventListener('DOMContentLoaded',function(){
		var rightmenu = document.getElementById('rightmenu');

		document.oncontextmenu = function(event){
			event.preventDefault();

			rightmenu.style.display = "none";
			rightmenu.style.display = "block";
			rightmenu.style.left = event.offsetX+'px';
			rightmenu.style.top = event.offsetY+'px';
		}

		document.onclick=function(event){
			rightmenu.style.display="none"
		}
	})
</script>

首先将浏览器的右键默认行为关闭。接下来设置右键行为,左箭可以取消掉右键菜单。

这样的功能并不完善,需要给每一个li写一个BOM事件,这里进行了省略。

这样实现起来还是比较麻烦的。因为我们在Graph中使用了EChart,所以我接着去查看EChart的菜单实现方法。

EChart添加右键点击菜单

新增'CONTEXTMENU'事件:

var ZR_EVENT_LISTENS = [
        'CLICK',
        'DBLCLICK',
        'CONTEXTMENU',
        'MOUSEOVER',
        'MOUSEOUT',
        'DRAGSTART',
        'DRAGEND',
        'DRAGENTER',
        'DRAGOVER',
        'DRAGLEAVE',
        'DROP'
    ];

_oncontextmenu: function (param) {
    //if(arguments[0].event.button == '2'){
    //    callChartListMethodReverse(this, 'onmousedown', param);
        if (param.target) {
            var ecData = this._eventPackage(param.target);
            if (ecData && ecData.seriesIndex != null) {
                this._messageCenter.dispatch(ecConfig.EVENT.CONTEXTMENU, param.event, ecData, this);
            }
        }
    //}
},

现在对界面文件进行一些说明,下面模拟了某些血缘分析的静态数据(项目是从后台查出的,这里就只能随便模拟一些数据看效果了),准备一个div,用来定义右键菜单:

<div id="menuuu"  onMouseLeave ="this.style.display = 'none';">
        <ul><!--右键弹出菜单-->        
            <li id="menu_blood" onClick="alert('血缘分析');" onMouseOver="this.style.background = '#999999';" onMouseOut="this.style.background = '#CCCCCC';">
                <img src="menu_blood.png" /><font>血缘分析</font>
            </li>
            <li id="menu_influence" onClick="alert('影响分析');" onMouseOver="this.style.background = '#999999';" onMouseOut="this.style.background = '#CCCCCC';">
                <img src="menu_influence.png" /><font>影响分析</font>
            </li>
        </ul>
    </div>

声明使用到右键菜单事件:

function rightBt(param){
    var menu = document.getElementById("menuuu");
    var event = param.event;
    var pageX = event.pageX;
    var pageY = event.pageY;
    menu.style.left = pageX + 'px';
    menu.style.top = pageY + 'px';
    menu.style.display = "block";
}
                            
//myChart.on(ecConfig.EVENT.CLICK, focus);
//myChart.on(ecConfig.EVENT.MOUSEDOWN, rightBt);
myChart.on(ecConfig.EVENT.CONTEXTMENU, rightBt);

以上就是demo的源码,效果如下:

img

基本符合项目的要求

参考资料

https://www.runoob.com/tags/att-global-contextmenu.html

https://www.cnblogs.com/ilinuxer/p/5281525.html

https://www.jianshu.com/p/2f6c9266d14c

原文地址:https://www.cnblogs.com/chai-bo/p/12969798.html