JavaScript实现右键菜单

1、代码实现

window.onload = function () {
  (function () {
    // 自定义右键菜单内容并插入到body最后一个节点前
    let dom = `
      <div id="rightMenuBars">
          <div class="rightMenu-group rightMenu-small">
              <div class="rightMenu-item">
                  <i class="fa fa-chevron-left" aria-hidden="true"></i>
              </div>
              <div class="rightMenu-item">
                  <i class="fa fa-chevron-right" aria-hidden="true"></i>
              </div>
              <div class="rightMenu-item">
                  <i class="fa fa-refresh" aria-hidden="true"></i>
              </div>
              <div class="rightMenu-item">
                  <i class="fa fa-chevron-up" aria-hidden="true"></i>
              </div>
          </div>
      </div>
      <div id="rightMenuLinks">
          <div class="rightMenu-group rightMenu-line">
              <a class="rightMenu-item">
                  <i class="fa fa-photo" aria-hidden="true"></i>
                  <span>蓝猫图床</span>
              </a>
              <a class="rightMenu-item">
                  <i class="fa fa-cloud" aria-hidden="true"></i>
                  <span>个人云盘</span>
              </a>
              <a class="rightMenu-item">
                  <i class="fa fa-book" aria-hidden="true"></i>
                  <span>书籍阅读</span>
              </a>
              <a class="rightMenu-item">
                  <i class="fa fa-external-link" aria-hidden="true"></i>
                  <span>接口文档</span>
              </a>
          </div>
      </div>
      `;
    let rightMenuDiv = document.createElement("div");
    rightMenuDiv.id = "rightMenu";
    let body = document.body;
    rightMenuDiv.innerHTML = dom;
    body.insertBefore(rightMenuDiv, body.lastChild);

    // 引入外部css文件
    let link = document.createElement("link");
    link.rel = "stylesheet";
    link.type = "text/css";
    link.href =
      "https://static.likepoems.com/cdn/common/botui/releases/v4.7.0/css/font-awesome.min.css";
    document.head.appendChild(link);

    /* 创建style标签并设置菜单样式 */
    let rightMenuStyle = document.createElement("style");
    rightMenuStyle.innerHTML =
      "#rightMenu{display:none;font-size:20px;position:fixed;padding:0 0.25rem;width:9rem;height:fit-content;top:10%;left:10%;background-color: rgb(calc(0 + 255 * 0.92), calc(150 + (255 - 150) * 0.92), calc(136 + (255 - 136) * 0.92));;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);transform:translateZ(0);color:#32325d;border-radius:12px;z-index:999;border:1px solid #e3e8f7;user-select:none;box-shadow:0 0 12px 4px rgba(0,0,0,0.05);transition:border 0.3s;font-weight:500;}#rightMenu:hover{border:1px solid #009688;box-shadow:0 8px 12px -3px #4259ef23;}#rightMenu .rightMenu-group{padding:0.35rem 0.3rem;transition:0.3s;}#rightMenu .rightMenu-line{border-top:1px dashed #4259ef23;}#rightMenu .rightMenu-group.rightMenu-small{display:flex;justify-content:space-between;}#rightMenu .rightMenu-group .rightMenu-item{border-radius:8px;transition:0.3s;}#rightMenu .rightMenu-line .rightMenu-item{margin:0.25rem 0;padding:0.25rem 0;}#rightMenu .rightMenu-group a{background-color:transparent;color:#32325d;text-decoration:none;transition:all 0.2s ease 0s;overflow-wrap:break-word;-webkit-user-drag:none;}#rightMenu .rightMenu-group.rightMenu-line .rightMenu-item{display:flex;}#rightMenu .rightMenu-group .rightMenu-item:hover{cursor: pointer !important;background-color:#009688;color:#fff;box-shadow:0 8px 12px -3px #4259ef23;}#rightMenu .rightMenu-group .rightMenu-item i{display:inline-block;text-align:center;line-height:1.5rem;width:1.5rem;padding:0 0.25rem;font-size:18px;color:#32325d;}#rightMenu .rightMenu-line .rightMenu-item i{margin:0 0.25rem;}#rightMenu .rightMenu-group .rightMenu-item span{line-height:1.5rem;}.rightMenu-small .rightMenu-item{width:30px;height:30px;line-height:30px;display:flex;align-items:center;justify-content:center;}";
    document.getElementsByTagName("head").item(0).appendChild(rightMenuStyle);
  })();

  // 如果菜单已经存在
  let rightMenu = document.getElementById("rightMenu");
  if (rightMenu) {
    // 定义菜单显示与隐藏的方法
    let rm = {};
    rm.showRightMenu = function (e, t = 0, l = 0) {
      let o = rightMenu;
      o.style.cssText = `top: ${t}px; left: ${l}px`;
      e ? (o.style.display = "block") : (o.style.display = "none");
    };
    rm.hideRightMenu = function () {
      rm.showRightMenu(!1);
    };
    let rmWidth = parseInt(rightMenu.style.width);
    let rmHeight = parseInt(rightMenu.style.height);

    // 定义键盘事件(主要用于屏蔽鼠标右键以及禁止打开开发者工具)
    document.onkeydown = () => {
      let e = window.event || arguments[0];
      //屏蔽F12
      if (e.keyCode == 123) {
        return false;
        //屏蔽Ctrl+Shift+I
      } else if (e.ctrlKey && e.shiftKey && e.keyCode == 73) {
        return false;
        //屏蔽Shift+F10
      } else if (e.shiftKey && e.keyCode == 121) {
        return false;
      }
    };

    // 鼠标右键按下的事件
    window.oncontextmenu = function (e) {
      // 阻止默认行为
      e.preventDefault();
      e = e || window.event;
      // 当可视宽度 > 768时显示菜单
      if (document.body.clientWidth > 768) {
        let t = e.clientY;
        let l = e.clientX + 10;
        return (
          (rmWidth = rmWidth || 155),
          (rmHeight = rmHeight || 255),
          l + rmWidth > window.innerWidth && (l -= rmWidth + 10),
          t + rmHeight > window.innerHeight &&
            (t -= t + rmHeight - window.innerHeight),
          rm.showRightMenu(!0, t, l),
          !1
        );
      }
    };

    // 鼠标按下事件(点击除去菜单的其它区域)
    document.addEventListener("click", (e) => {
      // 如果当前元素或祖先元素中存在rightMenu,则隐藏
      if (!e.target.closest("#rightMenu")) {
        rightMenu.style.display = "none";
      }
    });

    // 点击菜单操作栏图标的事件
    document.getElementById("rightMenuBars").addEventListener("click", (e) => {
      const inner = e.target?.className;
      switch (inner) {
        case "fa fa-chevron-left":
          // 向后
          history.back();
          break;
        case "fa fa-chevron-right":
          // 向前
          history.forward();
          break;
        case "fa fa-refresh":
          // 刷新
          window.location.reload();
          break;
        case "fa fa-chevron-up":
          // 回到顶部
          // 获取点击时的scrollTop值
          let scrollTop = document.documentElement.scrollTop - 0;
          let t = setInterval(function () {
            // 缓动动画,每次走剩余距离的一半
            scrollTop = scrollTop / 2;
            // 定义临界值
            if (scrollTop <= 5) {
              clearInterval(t);
              scrollTop = 0;
            }
            document.documentElement.scrollTop = scrollTop + 0;
          }, 16.666);
          break;
      }
      rm.hideRightMenu();
    });

    // 点击菜单显示栏文字事件
    document.getElementById("rightMenuLinks").addEventListener("click", (e) => {
      const tag = e.target?.tagName?.toLowerCase();
      const inner = e.target?.innerText;
      if (tag === "a" || tag === "span" || tag === "i") {
        rm.hideRightMenu();
      }
      switch (inner) {
        case "蓝猫图床":
          window.open("https://bluecat.likepoems.com");
          break;
        case "个人云盘":
          window.open("https://pan.likepoems.com");
          break;
        case "接口文档":
          window.open("https://api.likepoems.com/");
          break;
        case "书籍阅读":
          window.open("https://reader.likepoems.com/");
          break;
      }
    });
  }
};

2、效果演示

博客右键菜单js实现"

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

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

相关文章

【应用程序启动过程-三种加载控制器的方式-上午内容复习 Objective-C语言】

一、我们先来回忆一下,上午所有内容 1.首先呢,我们先说的是这个“应用程序启动过程”, 应用程序启动过程里面,有三方面内容 1)UIApplication对象介绍 2)AppDelegate对象介绍 3)应用程序启动过程 现在不知道大家对这个应用程序启动过程有印象吗, 2.首先,这个UIAp…

渗透测试高级技巧(一):分析验签与前端加密

“开局一个登录框” 在黑盒的安全测试的工作开始的时候&#xff0c;打开网站一般来说可能仅仅是一个登录框&#xff1b;很多时候这种系统往往都是自研或者一些业务公司专门研发。最基础的情况下&#xff0c;我们会尝试使用 SQL 注入绕过或者爆破之类的常规手段&#xff0c;如果…

开源计算机视觉库OpenCV详解

目录 1、概述 2、OpenCV详细介绍 2.1、OpenCV的起源 2.2、OpenCV开发语言 2.3、OpenCV的应用领域 3、OpenCV模块划分 4、OpenCV源码文件结构 4.1、根目录介绍 4.2、常用模块介绍 4.3、CUDA加速模块 5、OpenCV配置以及Visual Studio使用OpenCV 6、关于Lena图片 7、…

简于外 强于内,联想全新ThinkCentre M90a Pro Gen4以强劲性能开启商用新体验

近日&#xff0c;联想发布了最新一代商用台式一体机联想ThinkCentre M90a Pro Gen4。作为联想ThinkCentre M大师系列的旗舰产品&#xff0c;其配备了优质的显示屏&#xff0c;拥有强大的性能和稳定安全的特性&#xff0c;能够满足多样的工作场合&#xff0c;为商用一体机的行业…

面试题:你怎么理解System.out.println() ?

文章目录 首先分析System源码out源码分析println分析拓展知识点 你如何理解System.out.println() ? 学了这么久的面向对象编程&#xff0c;那如何用一行代码体现呢&#xff1f; 如果你能自己读懂System.out.println()&#xff0c;就真正了解了Java面向对象编程的含义 面向对…

Ajax入门-Express框架介绍和基本使用

电脑实在忒垃圾了&#xff0c;出现问题耗费了至少一刻钟time&#xff0c;然后才搞出来正常的效果&#xff1b; 效果镇楼 另外重新安装了VScode软件&#xff0c;原来的老是报错&#xff0c;bug。。&#xff1b; 2个必要的安装命令&#xff1b; 然后建立必要的文件夹和文件&…

MAX/MSP SDK学习07:list传递

实现自定义Obejct&#xff0c;要求将传入的一组数据100后传出。 #include "ext.h" #include "ext_obex.h" typedef struct _listTrans {t_object ob;void* outLet;t_atom* fArr;long listNum;} t_listTrans;void* listTrans_new(t_symbol* s, long arg…

【资深硬件工程师总结-千兆以太网设计指南】

文章目录 01通用PCB布线指南02标志焊盘中的接地过孔区示例03EMI注意事项04ESD注意事项 资深硬件工程师总结-千兆以太网设计指南 本应用笔记旨在帮助客户使用Microchip的10/100/1000 Mbps以太网器件系列设计PCB。本文档提供有关PCB布线的建 议&#xff0c; PCB 布线是保持信号完…

想分析全国用电及煤气、液化石油气供应利用情况,这部分数据对你有帮助!

随着经济的发展和人民生活水平的提高&#xff0c;能源的需求量越来越大。其中&#xff0c;电力和煤气、液化石油气等能源的供应利用情况与我们的日常生活息息相关。 今天我们根据《中国城市统计年鉴》统计的中国地级及以上城市的煤气及液化石油气供应及利用情况的指标&#xff…

【并发编程】ThreadLocal详解与原理

&#x1f4eb;作者简介&#xff1a;小明Java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…

Redis整数集合

前言 整数集合(intset)是集合键的底层实现之一&#xff0c;当一个集合只包含整数值元素&#xff0c;并且这个集合的元素数量不多时&#xff0c;Redis就会使用整数集合作为集合键的底层实现。 一. 整数集合的实现 1.1 结构 整数集合(intset)是Redis用于保存整数值的集合抽象数据…

【Linux】进程间通信——进程间通信的介绍和分类、管道、匿名管道、命名管道、匿名管道与命名管道的区别

文章目录 进程间通信1.进程间通信的介绍1.1目的和发展 2.进程间通信分类3.管道3.1匿名管道3.1.1匿名管道的原理&#xff08;文件角度&#xff09;3.1.2匿名管道的原理&#xff08;内核角度&#xff09;3.1.3管道读写规则3.1.4管道特点 3.2命名管道3.2.1创建命名管道3.2.2命名管…

【计算机网络学习之路】TCP socket编程

文章目录 前言一. 服务器1. 初始化服务器2. 启动服务器 二. 客户端三. 多进程服务器结束语 前言 本系列文章是计算机网络学习的笔记&#xff0c;欢迎大佬们阅读&#xff0c;纠错&#xff0c;分享相关知识。希望可以与你共同进步。 本篇博客基于UDP socket基础&#xff0c;介绍…

【SpringCloud】认识微服务、服务拆分以及远程调用

SpringCloud 1.认识微服务 1.1单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署 单体架构的优缺点&#xff1a; 优点&#xff1a; 架构简单&#xff0c;部署成本低 缺点&#xff1a; 耦合度高&#xff08;维护困难&#x…

设备状态监测与故障诊断系统的作用

随着工业生产的发展和技术的进步&#xff0c;设备状态监测与故障诊断系统在工业领域中扮演着越来越重要的角色。这一系统通过实时监测设备的状态和参数&#xff0c;及时发现潜在的故障&#xff0c;并提供预警信号&#xff0c;以降低生产中断、提高安全性和维护效率。以下将详细…

Django 模型和Admin站点管理(三)

一、定义模型 &#xff08;1&#xff09; 创建模型类&#xff0c;必须要继承自 models.Model from django.db import models# Create your models here. #设计数据库 #创建模型 class UserModel(models.Model):namemodels.CharField(max_length30) #对应于SQL name varchar(30…

慕尼黑电子展Samtec Demo | 回环测试带来Samtec产品组合优异表现

【摘要/前言】 大家好&#xff01;Electronica虎家展台Demo系列回来咯。 实践出真知&#xff0c;再好的纸面数据都不如来一场实际的测试和演示。Samtec团队始终在努力为客户带来卓越的产品和优质服务。而这其中&#xff0c;Demo演示的存在至关重要。演示过程可以为大家带来了…

ubuntu编译sqlite3并使用

SQLite3是一种轻量级的关系型数据库管理系统&#xff0c;它是在C语言基础上实现的。SQLite3具有许多优点&#xff0c;例如&#xff1a; 1.灵活&#xff1a;它可以在多种操作系统上运行&#xff0c;并且可以将多个数据库文件合并成一个文件。 2.易于使用&#xff1a;SQLite3使用…

“云浮云福保”暖心回归! 保障升级价格不变,医保个账可为全家缴费!

11月22日&#xff0c;2024年“云浮云福保”项目启动会在广东省云浮市迎宾馆成功举办。记者在会上获悉&#xff0c;“云浮云福保”是在云浮市医疗保障局、云浮市金融工作局、国家金融监督管理总局云浮监管分局指导下&#xff0c;的指导下&#xff0c;由中国人民财产保险股份有限…

网络安全之渗透测试入门准备

渗透测试入门所需知识 操作系统基础&#xff1a;Windows&#xff0c;Linux 网络基础&#xff1a;基础协议与简单原理 编程语言&#xff1a;PHP&#xff0c;python web安全基础 渗透测试入门 渗透测试学习&#xff1a; 1.工具环境准备&#xff1a;①VMware安装及使用&#xff1b…
最新文章