使用原生 HTML/CSS/JS 来实现右键菜单,支持二级菜单,支持窗口边沿自动调整位置 - 源码免费分享!
摘要:本文介绍了一种JavaScript实现的右键菜单,通过监测窗口大小和用户点击位置动态调整菜单的位置,确保在用户点击边界时不会遮挡菜单。代码展示了如何处理右键点击事件、菜单显示和二级菜单的隐藏与显示。
话不多说,先上截图:

上图是常规屏幕位置点击的效果。
以下是左上角,右上角,左下角,右下角,点击的效果图片:
左上角:

右上角:

左下角

右下角:

以上是关于JS自定义右键菜单的截图。
大家可以点击以上演示地址,查看实际的效果!
以下是代码讲解:
需要注意的就是边界检测处理,到极端点击底部和右侧时如果不做处理会遮挡菜单,影响使用,我的解决方案是动态监测窗口的宽高,根据右击时的横纵坐标判断菜单的最终位置,如果 右击的纵坐标+菜单高度 >= 窗口高度 则将菜单显示的高度坐标定位菜单高度,防止下方遮挡,如果 右击的横坐标+菜单宽度 >=> 窗口的宽度则菜单横坐标为窗口宽度减去两倍的窗口宽度,避免菜单遮挡。
HTML部分:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>右键菜单</title> <!-- 阿里图标 --> <link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/c/font_4453355_yizetjv4jeo.css" /> </head> <body> <!-- 右键点击测试区域 --> <div id="test-area"> <div class="tip"> 点击右键查看效果 </div> </div> <!-- 右键菜单1 --> <div class="menu" id="right-menu" hidden> <ul> <li><i class="iconfont icon-chakan1"></i>查看详情</li> <li><i class="iconfont icon-chakanziduan"></i>打开表字段提示</li> <hr /> <li><i class="iconfont icon-chakansql"></i>在SQL编辑器查看数据</li> <li><i class="iconfont icon-a-Property1shengchengshuju"></i>生成测试数据</li> <li><i class="iconfont icon-jurassic_export-data"></i>导出数据</li> <li><i class="iconfont icon-jurassic_import-data"></i>导入数据</li> <li><i class="iconfont icon-shujuqianyi_huaban"></i>数据迁移</li> <li><i class="iconfont icon-biaogeduibi"></i>表结构对比</li> <hr /> <li id="generate-sql"> <div class="link"> <span><i class="iconfont icon-shengchengSQL"></i>生成SQL</span> <span>></span> </div> <div class="submenu menu" id="right-menu2"> <ul> <li>查找</li> <li>插入</li> <li>更新</li> <li>删除</li> <li>DDL</li> </ul> </div> </li> <li id="copy"> <div class="link"> <span><i class="iconfont icon-fuzhi"></i>复制</span> <span>></span> </div> <div class="submenu menu" id="right-menu3"> <ul> <li>Insert语句</li> <li>CVS语句</li> </ul> </div> </li> <li><i class="iconfont icon-shanchu"></i>删除</li> <li><i class="iconfont icon-zhongmingming"></i>重命名</li> <hr /> <li><i class="iconfont icon-shuaxin"></i>刷新</li> </ul> </div> </body> </html>
js部分:
//获取窗口内部大小
var width = window.innerWidth;
var height = window.innerHeight;
//用于重新计算窗口大小
window.addEventListener('resize', ()=>{
width = window.innerWidth;
height = window.innerHeight;
})
//默认隐藏右键菜单
hiddenRightMenu('right-menu');
document.getElementById("test-area").addEventListener('contextmenu', (e) => {
e.preventDefault(e); //覆盖原生右键事件
showRightMenu(e, 'right-menu'); //显示菜单
})
document.getElementById("test-area").addEventListener('click', (e) => {
hiddenRightMenu('right-menu');
})
function showRightMenu(e, id) {
var rightMenu = document.getElementById(id);
if(e.clientY + 520 >= height){
rightMenu.style.top = (height - 530) + "px";
}else{
rightMenu.style.top = e.clientY + "px";
}
if(e.clientX + 200 >= width){
rightMenu.style.left = (width - 400) + "px";
}else{
rightMenu.style.left = e.clientX + "px";
}
// rightMenu.style.left = e.clientX + "px";
// rightMenu.style.top = e.clientY + "px";
rightMenu.style.display = 'block';
}
function hiddenRightMenu(id) {
document.getElementById(id).style.display = 'none';
}
//二级菜单事件
document.getElementById('generate-sql').addEventListener('mouseover', (e) => {
document.getElementById('right-menu2').style.display = 'block';
})
document.getElementById('generate-sql').addEventListener('mouseout', (e) => {
document.getElementById('right-menu2').style.display = 'none';
})
document.getElementById('copy').addEventListener('mouseover', (e) => {
document.getElementById('right-menu3').style.display = 'block';
})
document.getElementById('copy').addEventListener('mouseout', (e) => {
document.getElementById('right-menu3').style.display = 'none';
})CSS部分:
html,
body {
margin: 0;
overflow: hidden;
width: 100%;
}
#test-area {
border: 1px solid black;
width: 100%;
height: 100vh;
background-color: #333333;
display: flex;
align-items: center;
justify-content: center;
}
.menu {
width: 200px;
display: flex;
flex-direction: column;
position: absolute;
border: 1px solid gray;
background-color: #333333;
color: white;
border-radius: 4px;
font-size: 14px;
}
.menu>ul {
list-style: none;
padding: 0;
margin: 0;
}
.menu>ul>li {
padding: 10px;
cursor: pointer;
}
.menu>ul>li:hover {
background-color: #1A6CE7;
}
hr {
margin: 0;
border: 1px solid gray;
}
.submenu {
padding: 0;
left: 200px;
margin-top: -32px;
position: absolute;
display: none;
}
.link {
display: flex;
align-items: center;
justify-content: space-between;
}
.iconfont {
font-size: 14px;
padding-right: 5px;
}
.tip {
font-size: 40px;
color: gray;
}完整代码包下载:点击下载
参考文献:
1、基于Uni-app前端框架的SUMER UI3.0组件库
2、uniapp精仿支付宝UI界面源码下载,基于SumerUI一款仿支付宝APP
3、uniapp精仿微信源码,基于SumerUI一款仿微信APP应用
SUMER UI【用于开发APP、小程序、H5网站、毕业设计…】
评论