layui扩展组件之----右键菜单
源码:rightmenu.js
layui.define(['element'], function (exports) {let element = layui.element;const $ = layui.jquery;let MOD_NAME = 'rightmenu';let RIGHTMENUMOD = function () {this.v = '1.0.0';this.author = 'raowenjing';};String.prototype.format = function () {if (arguments.length == 0) return this;let param = arguments[0];let s = this;if (typeof(param) == 'object') {for (var key in param) s = s.replace(new RegExp("\\{" + key + "\\}", "g"), param[key]);return s;} else {for (var i = 0; i < arguments.length; i++) s = s.replace(new RegExp("\\{" + i + "\\}", "g"), arguments[i]);return s;}}function createStyle(ulClassName) {let style = '.{name} {position: absolute;width: 110px;z-index: 9999;display: none;background-color: #fff;padding: 2px;color: #333;border: 1px solid #c2c2c2;border-radius: 2px;cursor: pointer;}.{name} li {text-align: center;display: block;height: 30px;line-height: 32px;}.{name} li:hover {background-color: #666;color: #fff;}'.format({name: ulClassName});return style;}/*** 初始化*/RIGHTMENUMOD.prototype.render = function (opt) {createStyle();if (!opt.container) {console.error("[ERROR]使用rightmenu组件需要制定'container'属性!");return;}let defaultNavArr = [];opt = opt || {};opt.triggerDom = opt.triggerDom || "li";opt.boxClassName = opt.boxClassName || "right-click-menu-container";opt.navArr = opt.navArr || defaultNavArr;CreateRightMenu(opt,"");_CustomRightClick(opt);};/*** 创建右键菜单项目* @param rightMenuConfig* @constructor*/function CreateRightMenu(rightMenuConfig,currentData,callback) {if($('.'+rightMenuConfig.boxClassName).length>0) $('.'+rightMenuConfig.boxClassName).remove();$("<style></style>").text(createStyle(rightMenuConfig.boxClassName)).appendTo($("head"));let li = '';$.each(rightMenuConfig.navArr, function (index, conf) {if(!!currentData && typeof conf.showFormat != "undefined"){ // 控制if(typeof conf.showFormat == "function"){var isShow = conf.showFormat(currentData);isShow = !!isShow?true:false;if(isShow){li += '<li data-type="{eventName}"><i class="layui-icon {icon}"></i>{title}</li>'.format({eventName:conf.eventName,icon:conf.icon?conf.icon:"",title:conf.title});}}else{if(!!conf.showFormat){li += '<li data-type="{eventName}"><i class="layui-icon {icon}"></i>{title}</li>'.format({eventName:conf.eventName,icon:conf.icon?conf.icon:"",title:conf.title});}}}else{li += '<li data-type="{eventName}"><i class="layui-icon {icon}"></i>{title}</li>'.format({eventName:conf.eventName,icon:conf.icon?conf.icon:"",title:conf.title});}})let tmpHtml = '<ul class="{className}">{liStr} </ul>'.format({liStr: li, className: rightMenuConfig.boxClassName})$(rightMenuConfig.container).after(tmpHtml);setTimeout(function(){registerMenuClick(rightMenuConfig);if(!!callback && typeof callback == "function") callback();},10)}/*** 绑定右键菜单* @constructor*/function _CustomRightClick(rightMenuConfig) {$(rightMenuConfig.container).off("click");$(rightMenuConfig.container).on("click", rightMenuConfig.triggerDom,function () {$('.'+rightMenuConfig.boxClassName).hide();});$(rightMenuConfig.container).off("contextmenu")$(rightMenuConfig.container).on("contextmenu", rightMenuConfig.triggerDom, function (e) {// 阻止默认的右键菜单e.preventDefault();// 重构菜单CreateRightMenu(rightMenuConfig,$(this).data(),function(){let popupmenu = $("."+rightMenuConfig.boxClassName);let leftValue = ($(document).width() - e.clientX) < popupmenu.width() ? (e.clientX - popupmenu.width()) : e.clientX;let topValue = ($(document).height() - e.clientY) < popupmenu.height() ? (e.clientY - popupmenu.height()) : e.clientY;popupmenu.css({left: leftValue, top: topValue}).show();});// 将该元素的所有数据复制到$.each($(this).data(), function(key, value) {$("."+rightMenuConfig.boxClassName).data(key, value);});return false;});// 点击空白处隐藏弹出菜单$(document).click(function (event) {event.stopPropagation();$("."+rightMenuConfig.boxClassName).hide();});}function registerMenuClick(rightMenuConfig){$('.' + rightMenuConfig.boxClassName + ' li').prop("onclick",null).off("click");/*** 注册tab右键菜单点击事件*/$('.' + rightMenuConfig.boxClassName + ' li').click(function () {rightMenuConfig.registMethod[$(this).attr("data-type")]($(this).parents("."+rightMenuConfig.boxClassName).data());$("."+rightMenuConfig.boxClassName).hide();})}let rightmenuObj = new RIGHTMENUMOD();exports(MOD_NAME, rightmenuObj);
})
使用示例:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>标题</title>
</head>
<body><div id="app_folder" lay-filter="folder_filter" class="folder-container"></div><script src="./js/jquery.min.js"></script><script src="./layui/layui.js"></script><script>layui.config({base: './layui/modules/' //静态资源所在路径}).use(['rightmenu','tree'], function(){var tree = layui.tree, rightmenu_ = layui.rightmenuinitFolder();function initFolder(){var data = [{ id: 1, title: "标题标题标题", type: "html" },{ id: 2, title: "标题标题标题", type: "html", children: [ { id: 3, title: "标题", type: "javascript" } ] },]tree.render({elem: '#app_folder' //默认是点击节点可进行收缩,data: data,onlyIconControl: true,click: function(obj){}});setTimeout(function(){// 为dom节点添加数据$("#app_folder .layui-tree-main").each(function(index,item){var parent = $(this).parent().parent();var id = parent.data("id");var dataItem = null;if(parent.hasClass("layui-tree-setHide")){ // 页面dataItem = data.find(function(it){ return it.id==id; })}else{ // 资源for(var i=0,len=data.length;i<len;i++){var currentItem = data[i].children.find(function(it){ return it.id==id; })if(!!currentItem) dataItem = currentItem;}}if(!!dataItem){for (var key in dataItem) {$(this).data(key,dataItem[key]);}}})rightmenu_.render({container: '#app_folder',triggerDom: ".layui-tree-main", // 触发右击事件的dom节点// navArr:对象数组,每个对象包含eventName、title、showFormat属性navArr: [{title: "新建页面", eventName: 'createPage'},{title: "新建资源", eventName: 'createSource'},{title: "修改", eventName: 'edit'},{title: "删除", eventName: 'delete'},{title: "预览", eventName: 'preview', showFormat: function(data){ if(data.source_type=="html"){ return true }else{ return false; } } },{title: "资源路径", eventName: 'sourcePath', showFormat: function(data){ if(data.source_type=="html"){ return true }else{ return false; } } },{title: "下载资源", eventName: 'downloadSource', showFormat: function(data){ if(data.source_type=="image" || data.source_type=="file"){ return true }else{ return false; } } },{title: "清除缓存数据", eventName: 'clearLocalData', showFormat: function(data){ if(data.source_type=="javascript"){ return true }else{ return false; } } }],// 注册自定义事件registMethod: {'clearLocalData': function(data){console.log(data);},'sourcePath': function(data){console.log(data);},'preview': function(data){},'downloadSource': function(data){},'edit': function(data){},'delete': function(data){},'createPage': function(data){},'createSource': function(data){},}})},100);}})</script>
</body>
</html>
效果:
相关文章:

layui扩展组件之----右键菜单
源码:rightmenu.js layui.define([element], function (exports) {let element layui.element;const $ layui.jquery;let MOD_NAME rightmenu;let RIGHTMENUMOD function () {this.v 1.0.0;this.author raowenjing;};String.prototype.format function () {…...

ue5实现数字滚动增长
方法1 https://www.bilibili.com/video/BV1h14y197D1/?spm_id_from333.999.0.0 b站教程 重写loop节点 方法二 写在eventtick里...

Flink(一)
目录 架构处理有界与无界数据部署应用到任意地方运行任意规模应用利用内存性能 流应用流处理应用的基本组件流状态时间 应用场景事件驱动应用事件驱动应用的优势Flink如何支持事件驱动应用? 典型的事件驱动示例 数据分析应用流式分析应用的优势?Flink 如…...

kaggle 数据集下载
文章目录 kaggle 数据集下载(1) 数据集下载(2) 手机号验证 kaggle 数据集下载 这两天想学习 kaggle 赛事 把深度学习相关的内容自己给过一遍,快忘得差不多了,惭愧。 参考了好多帖子,使用命令行…...

Linux shell编程学习笔记87:blkid命令——获取块设备信息
0 引言 在进行系统安全检测时,我们需要收集块设备的信息,这些可以通过blkid命令来获取。 1 blkid命令的安装 blkid命令是基于libblkid库的命令行工具,可以在大多数Linux发行版中使用。 如果你的Linux系统中没有安装blkid命令,…...

wireshark筛选条件整理
Wireshark筛选条件整理 一、MAC地址过滤二、IP地址过滤三、端口过滤四、协议筛选五、数据分析1、整体2、frame数据帧分析3、 Ethernet II 以太网4、IP协议5、TCP6、HTTP7、ARP8、DLEP动态链接交换协议 六、统计-协议分级(统计包占比) and && 、 …...
基于现代 C++17 的模块化视频质量诊断处理流程设计
文章目录 0. 引言1. 原始设计分析2. 新的设计思路2.1 定义通用的检测接口2.2 使用 std::function 和 std::any 管理检测模块2.3 构建可动态配置的检测管道 3. 示例实现3.1 定义检测接口和模块3.1.1 检测接口3.1.2 信号检测模块3.1.3 冻结检测模块3.1.4 其他检测模块 3.2 构建检…...
高级java每日一道面试题-2024年10月23日-JVM篇-说一下JVM有哪些垃圾回收算法?
如果有遗漏,评论区告诉我进行补充 面试官: 说一下JVM有哪些垃圾回收算法? 我回答: 在 Java 虚拟机 (JVM) 中,垃圾回收 (Garbage Collection, GC) 是一项非常重要的功能,用于自动管理应用程序的内存。JVM 采用多种垃圾回收算法来决定何时以及如何回收…...

高效文本编辑与导航:Vim中的三种基本模式及粘滞位的深度解析
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...

w005基于Springboot学生心理咨询评估系统
🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板ÿ…...

实战-任意文件下载
实战-任意文件下载 1、开局 开局一个弱口令,正常来讲我们一般是弱口令或者sql,或者未授权 那么这次运气比较好,直接弱口令进去了 直接访问看看有没有功能点,正常做测试我们一定要先找功能点 发现一个文件上传点,不…...
PG数据库之视图详解
1. 视图的基本定义 在PostgreSQL(简称pg)数据库中,视图(View)是一种虚拟表,其内容由SQL查询定义。视图并不实际存储数据,而是在每次查询时根据定义的查询语句动态生成结果。视图可以简化复杂的…...

时间序列预测(十五)——有关Python项目框架的实例分析
#1024程序员节|征文# 在之前的学习中,已经对时间序列预测的相关内容有了大致的了解。为了进一步加深理解,并能够将所学知识应用于实际中,我决定找一个完整的Python框架来进行深入学习。经过寻找,我终于找到了一篇非常具…...

ETL、ELT和反向ETL都有什么不同?怎么选择?
数据处理是现代企业中不可或缺的一部分。随着数据量的不断增长,如何高效地处理、转换和加载数据变得尤为重要。本文将介绍三种常见的数据处理方式:ETL、ELT和反向ETL,帮助读者更好地理解和选择适合自己业务需求的方式。 一、ETL 定义&#…...
linux 中文实用型手册 基于RHEL(红帽系)
硬件系统 Updated by wangjing on 2024-10-28 at 02:36:57 in Tongzhou District, Beijing. 硬件信息 机器型号 dmidecode | grep "Product Name"CPU型号 cat /proc/cpuinfo |grep "model name" | uniqWWWCPU详情 lscpuCPU个数 cat /proc/cpuinfo |grep &q…...

Hash表算法
哈希表 理论知识(本文来自于代码随想录摘抄)什么是哈希常见的三种哈希结数组:set:map:其他常用方法或者技巧(自己总结的) 练习题和讲解有效的字母移位词349. 两个数组的交集1. 两数之和454. 四数相加 II15. 三数之和 总…...

MySQL企业常见架构与调优经验分享
文章目录 一、选择 PerconaServer、MariaDB 还是 MYSQL二、常用的 MYSQL 调优策略三、MYSOL 常见的应用架构分享四、MYSOL 经典应用架构 观看学习课程的笔记,分享于此~ 课程:MySQL企业常见架构与调优经验分享 mysql官方优化文档 调优MySQL参数 一、选择 …...

C++引用类型变量
引用变量的主要用途是用作函数的形参。这样函数将使用原始数据,而不是副本。除指针之外,引用也为处理大型结构提供了一种非常方便的途径。 再C中使用&符号标识引用。也就是说C给&符号赋予了另一个含义,将其用来声明引用。 引用的声…...
《C++23 新特性:现代软件开发的变革力量》
在软件开发的快速演进中,C作为一种强大且广泛应用的编程语言,不断推陈出新以适应日益复杂的开发需求。C23 的到来,为现代软件开发带来了诸多新的机遇和挑战。它的新特性不仅影响着开发者的编程习惯,也在代码效率、可维护性以及软件…...
Educational Codeforces Round 88 E. Modular Stability
题目链接 Educational Codeforces Round 88 E. Modular Stability 思路 对于任意的非负整数 x x x,我们要满足 x % a % b x % b % a x \% a \% b x \% b \% a x%a%bx%b%a。因为 a < b a < b a<b,所以只有 b b b为 a a a的倍数时才满足条件…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...