前段时间写项目遇到了这个需求,今天写一个demo分享给大家,希望能对一些读者有些帮助。
思路:demo使用ul列表标签,搭建结构样式,使用v-show指令控制列表的显示与隐藏。给列表添加固定定位,给需要右击的容器添加相对定位并绑定contextmenu右击事件,在事件中阻止浏览器默认行为并获取鼠标右击的位置,将获取到的位置赋值给列表的top与left。最后监听v-show指令,点击其他区域时关闭右击列表。详细demo代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>右击菜单</title>
</head>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
position: relative;
width: 1200px;
height: 800px;
background-color: rgba(52, 42, 201, 0.5);
margin: 0 auto;
}
.contextmenu {
position: absolute;
width: 100px;
padding: 10px;
text-align: center;
background-color: #fff;
box-shadow: 2px 2px 30px 2px #888;
border-radius: 5px;
z-index: 999;
}
.contextmenu li {
list-style: none;
padding: 0 5px;
}
.contextmenu li:hover {
background-color: #c2c2c2;
cursor: pointer;
}
</style>
<body>
<div id="app">
<div class="container" @contextmenu.prevent="(e) => OpenMenu(e)">
<ul class="contextmenu" v-show="isOpenMenu" :style="`top: ${top}px; left: ${left}px;`">
<li>删除</li>
<li>复制</li>
<li>粘贴</li>
<li>重命名</li>
</ul>
</div>
</div>
<script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
isOpenMenu: false, // 右击列表的显示与隐藏
top: 0, // 控制列表的 纵向位置
left: 0 // 控制列表的 横向位置
}
},
watch: {
isOpenMenu(newVal) {
if (newVal) {
document.body.addEventListener('click', this.closeMenu) // isOpenMenu 为 true时,点击其他区域关闭列表
} else {
document.body.removeEventListener('click', this.closeMenu)// 为 false时,移除事件
}
}
},
methods: {
// 右击事件触发
OpenMenu(e) {
this.isOpenMenu = true // 打开右击列表
this.top = e.offsetY // 赋予纵向位置
this.left = e.offsetX // 赋予横向位置
},
// 关闭右击列表
closeMenu() {
this.isOpenMenu = false
}
}
})
</script>
</body>
</html>