注意点
- 右键菜单也要记得禁止默认事件
- 右键的同时保存数据,方便后续使用
- 右键后对页面添加点击事件,页面点击后隐藏右键菜单
- 查看右键菜单是相对于整个页面定位,还是相对于某个父元素定位的,因为定位的不同,通过事件对象获取鼠标坐标的方式也不同
- 相对于页面定位:使用 clientX、clientY(鼠标坐标以浏览器显示区域的左上角开始)
- 相对于某个父元素定位:使用 layerX、layerY(鼠标坐标以有定位属性的父元素左上角开始)
- 对鼠标坐标进行判断,限制菜单在可视区域内
效果
在指定元素右键后,显示右键菜单
html
<div class="g-resources-list">
<div class="g-resources-item" v-for="item in aResources" :key="item.id"
:style="{'backgroundColor': item.color}" @contextmenu.prevent="fnResourcesRightClick($event, item)">
{{item.name}}
</div>
</div>
<!-- 右键菜单 -->
<div id="rightMenu" v-show="bRightMenuVisible" class="g-menu" @contextmenu.stop.prevent>
<el-menu @select="fnRightMenuSelect" class="el-menu-vertical" active-text-color="#fff" text-color="#fff">
<el-menu-item index="1" class="menuItem" title="点击添加">
<i class="el-icon-folder-add"></i>
<span slot="title">添加</span>
</el-menu-item>
<el-menu-item index="2" class="menuItem" title="点击刷新">
<i class="el-icon-refresh-right"></i>
<span slot="title">刷新</span>
</el-menu-item>
</el-menu>
</div>
JavaScript
data() {
return {
aResources: [{
id: 1,
name: '我是资源一',
color: '#c3d08b'
}, {
id: 2,
name: '我是资源二',
color: '#f9cc9d'
}, {
id: 3,
name: '我是资源三',
color: '#fddd9b'
}], // 资源数据
bRightMenuVisible: false, // 是否显示右键菜单
oRightClickItem: null, // 保存右键资源数据,方便后续使用
}
},
methods: {
/*
右键点击资源
event ==> 事件对象
item ==> 资源数据
*/
fnResourcesRightClick(event, item) {
// 获取top、left 最大允许像素
let nScreenWidth = document.documentElement.clientWidth - 98;
let nScreenHeight = document.documentElement.clientHeight - 54;
// 菜单显隐
this.bRightMenuVisible = !this.bRightMenuVisible;
// 保存右键资源数据,方便后续使用
this.oRightClickItem = item;
document.addEventListener("click", () => {
// 页面点击隐藏菜单
this.bRightMenuVisible = false;
});
let oRightMenu = document.querySelector("#rightMenu");
// 确定菜单位置
if (event.clientX >= nScreenWidth) {
// 右键鼠标位置大于最大像素,取最大像素
oRightMenu.style.left = nScreenWidth + "px";
} else {
// 右键鼠标位置小于最大像素,取鼠标位置
oRightMenu.style.left = event.clientX + "px";
}
oRightMenu.style.top =
(event.clientY >= nScreenHeight ? nScreenHeight : event.clientY) + "px";
},
/*
右键菜单点击
key ==> 菜单序列
*/
fnRightMenuSelect(key) {
key = parseInt(key);
switch (key) {
case 1:
console.log('添加');
break;
case 2:
console.log('刷新');
break;
}
}
}
css
.g-container {
height: 100vh;
}
.g-resources-list {
display: flex;
}
.g-resources-list .g-resources-item {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
height: 280px;
}
.g-resources-list .g-resources-item+.g-resources-item {
margin-left: 10px;
}
/* 右键菜单 -- start */
.g-menu {
position: absolute;
width: 96px;
}
.g-menu .el-menu-item {
display: flex;
align-items: center;
width: 96px;
height: 26px;
padding: 0 !important;
line-height: 26px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
transition: all 0.3s;
}
.g-menu .el-menu-item i {
margin-left: 6px;
}
.g-menu .el-menu-item i.font_family {
margin: 0 7px 0 9px;
font-size: 18px;
}
.g-menu .el-menu-item.is-active i {
color: #909399;
}
.g-menu .el-menu-item:hover {
background-color: #09aaff;
}
.g-menu .el-menu-item:focus {
background-color: transparent;
}
.g-menu .el-menu-item:hover i,
.g-menu .el-menu-item:hover span {
color: #fff;
}
.g-menu .el-menu-item span {
height: 32px;
line-height: 35px;
font-size: 12px;
text-align: center;
color: #1a1a1a;
}
.g-menu .el-menu-vertical {
z-index: 999;
box-shadow: 0 0.5em 1em 0 rgba(0, 0, 0, 0.2);
border-radius: 1px;
}
/* 右键菜单 -- end */
参考链接
js鼠标事件 clientX、clientY、offsetX、offsetY、layerX、layerY、pageX、 pageY、screenX、screenY_蒲公英芽的博客-CSDN博客