原生 HTML/CSS/JS 实现右键菜单和二级菜单

9,870次阅读
没有评论

共计 3581 个字符,预计需要花费 9 分钟才能阅读完成。

文章来源:www.huhailong.vip 站点
文章源地址:https://www.huhailong.vip/article/1764653112011841538

Demo 效果演示地址
先看效果图
image.png{{{width=“auto”height=“auto”}}}

需要注意的就是边界检测处理,到极端点击底部和右侧时如果不做处理会遮挡菜单,影响使用,我的解决方案是动态监测窗口的宽高,根据右击时的横纵坐标判断菜单的最终位置,如果 右击的纵坐标 + 菜单高度 >= 窗口高度 则将菜单显示的高度坐标定位菜单高度,防止下方遮挡,如果 右击的横坐标 + 菜单宽度 >= 窗口的宽度则菜单横坐标为窗口宽度减去两倍的窗口宽度,避免菜单遮挡。

完整代码
DOCTYPE html>
html lang="en">

head>
    meta charset="UTF-8">
    meta name="viewport" content="width=device-width, initial-scale=1.0">
    title>右键菜单title>
    
    
    style>
        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;
        }
    style>
head>

body>
    
    div id="test-area">
        div class="tip">
            点击右键查看效果
        div>
    div>
    
    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>生成 SQLspan>
                    span>>span>
                div>
                div class="submenu menu" id="right-menu2">
                    ul>
                        li>查找li>
                        li>插入li>
                        li>更新li>
                        li>删除li>
                        li>DDLli>
                    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>
    script>


        
        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.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';
        })
    script>
body>

html>

原文地址: 原生 HTML/CSS/JS 实现右键菜单和二级菜单

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-11-07发表,共计3581字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)