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

文章来源: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>
    <!-- 阿里图标 -->
    <!-- <link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/c/font_4453355_yizetjv4jeo.css" /> -->
    <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>
    <!-- 右键菜单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>
    <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.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';
        })
    </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/488011.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ffmpeg拉流并解码

流程 注意事项 版本不同导致的api差异资源安全释放

【多模态融合】SuperFusion 激光雷达与相机多层次融合 远距离高清地图预测 ICRA 2024

前言 本文介绍激光雷达与相机进行多层次融合&#xff0c;包括数据级融合、特征级融合和BEV级融合。 融合后的BEV特征可以支持不同的任务头&#xff0c;包括语义分割、实例编码和方向预测&#xff0c;最后进行后处理生成高清地图预测&#xff0c;它是来自ICRA 2024的。 会讲解…

2002-2023年各地级市环境规制强度数据(环保词频统计)

2002-2023年各地级市环境规制强度数据&#xff08;环保词频统计&#xff09; 1、时间&#xff1a;2002-2023年 2、来源&#xff1a;政府工作报告 3、指标&#xff1a; 行政区划代码、年份、城市、所属省份、文本总长度、仅中英文-文本总长度、文本总词频-全模式、文本总词频…

四创科技解决方案

联合解决方案 推进智慧水利建设是推动新阶段水利高质量发展的六条实施路径之一,四创科技按照“需求牵引、应用至上、数字赋能、提升能代化能力”要求,以数字化、网络化、智能化为主线,以数字化场景、智慧化模拟、精准化决策为路径&#xff0c;以构建数字李生流域为核心,全面推进…

使用ChatGPT的场景之gpt写研究报告,如何ChatGPT写研究报告

推荐写研究报告使用智能站&#xff1a; dayfire.cn/ 1. 确定研究主题 明确主题&#xff1a;在开始之前&#xff0c;你需要有一个清晰的研究主题。这将帮助AI更好地理解你的需求…

关于 Flutter 项目中已为整个 APP 配置了主题颜色但是在 AppBar 等某些组件中主题颜色不生效的问题

这里需要先说明的&#xff0c;从 Flutter 2.5 开始&#xff0c;Flutter 团队开始慢慢移除ThemeData 中 primaryColor 属性对所有组件的影响&#xff0c;取而代之的是基于 ColorScheme 的 Color。因此&#xff0c;在 Flutter 2.5 之后为整个 APP 配置主题颜色&#xff0c;我们需…

告别信息差,一手地推拉新推广平台推荐

拥有一份稳定的主业固然重要&#xff0c;但app地推拉新副业的兴起也为我们提供了更多的可能性。它们不仅能为我们带来额外的收入&#xff0c;甚至有可能超越我们的主业。 今天&#xff0c;我们就给大家分享几个靠谱的地推拉新项目平台&#xff0c;让你告别信息差&#xff0c;稳…

Element-Plus下拉菜单边框去除教程

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

实战|使用 Node.js 和 htmx 构建全栈应用程序

在本教程中&#xff0c;我将演示如何使用 Node 作为后端和 htmx 作为前端来构建功能齐全的 CRUD 应用程序。这将演示 htmx 如何集成到全栈应用程序中&#xff0c;使您能够评估其有效性并确定它是否是您未来项目的不错选择。 htmx 是一个现代 JavaScript 库&#xff0c;旨在通过…

Redis中的事件

事件 概述 Redis服务器是一个事件驱动程序:服务器需要处理以下两类事件: 1.文件事件(file event):Redis服务器通过套接字与客户端(或者其他Redis服务器)进行连接&#xff0c;而文件事件就是服务器对套接字操作的抽象。服务器与客户端(或者其他服务器)的通信会产生相应的文件…

Web实现猜数字游戏:JavaScript DOM基础与实例教程

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

STM32学习笔记(6_5)- TIM定时器的输出捕获原理

无人问津也好&#xff0c;技不如人也罢&#xff0c;都应静下心来&#xff0c;去做该做的事。 最近在学STM32&#xff0c;所以也开贴记录一下主要内容&#xff0c;省的过目即忘。视频教程为江科大&#xff08;改名江协科技&#xff09;&#xff0c;网站jiangxiekeji.com 现在开…

Jmeter脚本优化——CSV数据驱动文件

使用 CSV 数据文件设置实现参数化注册 1&#xff09; 本地创建 csv 文件&#xff0c;并准备要使用的数据&#xff0c;这里要参数化的是注册的用户名和邮箱。所以在 csv 文件中输入多组用户名和邮箱。 2&#xff09; 通过测试计划或者线程组的右键添加->配置元件->CSV…

【日常记录】【CSS】css实现汉堡菜单

文章目录 1、介绍2、布局3、鼠标移入变成 X 1、介绍 在移动端或者响应式中&#xff0c;可能会遇到 三个横线 鼠标移动到的时候&#xff0c;会变成 一个 X 符号&#xff0c;这个就是汉堡菜单 2、布局 <style>* {margin: 0;padding: 0;box-sizing: border-box;}body {displ…

后端常见面经之JVM

JVM组成 有垃圾回收的是哪些地方&#xff1f; 垃圾回收主要是针对堆内存中的对象进行的&#xff0c;包括以下几个方面&#xff1a; 堆内存&#xff1a;垃圾回收主要针对堆内存中不再被引用的对象进行回收&#xff0c;包括新生代和老年代中的对象。 永久代/元空间&#xff1a…

跑腿小程序|基于微信小程序的跑腿平台小程序设计与实现(源码+数据库+文档)

跑腿平台小程序目录 目录 基于微信小程序的跑腿平台小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 1、用户信息管理 2、跑腿任务管理 3、任务类型管理 4、公告信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、…

【数据结构】非线性结构——二叉树

文章目录 前言1.树型结构1.1树的概念1.2树的特性1.3树的一些性质1.4树的一些表示形式1.5树的应用2.二叉树 2.1 概念2.2 两种特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储2.5 二叉树的基本操作 前言 前面我们都是学的线性结构的数据结构&#xff0c;接下来我们就需要来学习非…

42 ajax 下载文件未配置 responseType blob 导致的文件异常

前言 这是一个最近的关于文件下载碰到的一个问题 主要的情况是, 基于 xhr 发送请求, 获取下载的文件 然后 之后 xhr 这边拿到 字节序列之后, 封装 blob 来进行下载 然后 最开始我们这边没有配置 responseType 为 blob, arraybuffer, 然后 导致下载出来的 文件大小超过了…

基于前端技术实现的全面预算编制系统

前言 在现代商业环境中&#xff0c;预测销售数据和实际成本是每个公司CEO和领导都极为重视的关键指标。然而&#xff0c;由于市场的不断变化&#xff0c;准确地预测和管理这些数据变得愈发具有挑战性。为了应对这一挑战&#xff0c;建立一个高效的系统来管理和审查销售数据的重…

QT环境搭建

学习QT 一、QT环境搭建二、QT的SDK下载三、认识QT SDK 中自带的一些程序 一、QT环境搭建 QT开发环境&#xff0c;需要安装三个部分。 c编译器&#xff08;gcc、cl.exe……不是visual studio&#xff09;QT SDK&#xff08;QT SDK里面已经内置了C编译器&#xff1b;SDK就是软件…