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.rightmenu
        
            initFolder();

            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>

效果:

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

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

相关文章

本质矩阵分解计算Rt

1 本质矩阵的计算 上一文章中描述了本质矩阵的计算&#xff0c;计算机视觉-对极几何-CSDN博客&#xff0c;那么计算得到本质矩阵有什么用&#xff1f;其中一个应用是通过本质矩阵计算得到2D-2D的相对变换。 在相关矩阵计算时&#xff0c;一般会在两幅图像中&#xff0c;根据特征…

谷歌云GCP基础概念讲解

概览 云的基础是虚拟化&#xff1a;服务器&#xff0c;存储&#xff0c;网络。服务器是远程计算机的逻辑分区。存储是物理硬盘的逻辑划分。网络则是虚拟私有云。 谷歌是唯一一个拥有全球私有基础设施的公司&#xff1b;他们的谷歌云基础设施没有任何一部分通过公共互联网。换句…

HarmonyOS 组件样式@Style 、 @Extend、自定义扩展(AttributeModifier、AttributeUpdater)

1. HarmonyOS Style 、 Extend、自定义扩展&#xff08;AttributeModifier、AttributeUpdater&#xff09; Styles装饰器&#xff1a;定义组件重用样式   ;Extend装饰器&#xff1a;定义扩展组件样式   自定义扩展&#xff1a;AttributeModifier、AttributeUpdater 1.1. 区…

排序(一)插入排序,希尔排序,选择排序,堆排序,冒泡排序

目录 一.排序 1.插入排序 2.希尔排序 3.选择排序 4.堆排序 5.冒泡排序 二.整体代码 1.Sort.h 2.Sort.c 3.test.c 一.排序 1.插入排序 插入排序基本思想:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为 止…

【UE5.3 Cesium for Unreal】编译GlobePawn

目录 前言 效果 步骤 一、下载所需文件 二、下载CesiumForUnreal插件 三、处理下载的文件 四、修改代码 “CesiumForUnreal.uplugin”部分 “CesiumEditor.cpp”部分 “CesiumEditor.h”部分 “CesiumPanel.cpp”部分 “IonQuickAddPanel.cpp”部分 “IonQuickAd…

线程的理解及基本操作

目录 一、线程的理解 &#xff08;1&#xff09;什么是线程呢&#xff1f; &#xff08;2&#xff09;线程的优缺点及异常 二、线程的基本操作 &#xff08;1&#xff09;创建一个新的进程 &#xff08;2&#xff09;获取线程id &#xff08;3&#xff09;线程终止 &…

SpringBoot 集成RabbitMQ 实现钉钉日报定时发送功能

文章目录 一、RabbitMq 下载安装二、开发步骤&#xff1a;1.MAVEN 配置2. RabbitMqConfig 配置3. RabbitMqUtil 工具类4. DailyDelaySendConsumer 消费者监听5. 测试延迟发送 一、RabbitMq 下载安装 官网&#xff1a;https://www.rabbitmq.com/docs 二、开发步骤&#xff1a;…

AC的旁挂和直连的方式的使用场景

AC组网架构 AC中文含义为无线接入控制器&#xff0c;主要功能是可以批量配置和管理无线AP。经常工作在大中型园区网络、企业办公网络等应用场景。 下面来介绍一下无线AC的几种经典架构。 一1旁挂式组网 旁挂式组网顾名思义&#xff0c;就是旁挂在网络中&#xff0c;对AP来进行…

view design之table自定义单元格模版

View Design之table自定义单元格模版 在 columns 的某列声明 slot 后&#xff0c;就可以在 Table 的 slot 中使用参数。 slot 的参数有 3 个&#xff1a;当前行数据 row&#xff0c;当前列数据 column&#xff0c;当前行序号 index。 完整示例 <template><Table …

乘云而上,OceanBase再越山峰

一座山峰都是一个挑战&#xff0c;每一次攀登都是一次超越。 商业数据库时代&#xff0c;面对国外数据库巨头这座大山&#xff0c;实现市场突破一直都是中国数据库产业多年夙愿&#xff0c;而OceanBase在金融核心系统等领域的攻坚克难&#xff0c;为产业突破交出一副令人信服的…

在Ubuntu(Linux)系统下安装Anaconda3

1、到官网下载Linux版本的包&#xff1a;https://www.anaconda.com/download/success 2、到所在目录中&#xff0c;运行下方命令&#xff0c;Anaconda3-2024.06-1-Linux-x86_64.sh是下载包的名字 bash Anaconda3-2024.06-1-Linux-x86_64.sh输入yes确定 3、输入~/anaconda3/b…

MySQL数据库集群-PXC方案视频教程下载 MySQL架构设计及常见业务处理

MySQL数据库集群-PXC方案视频教程下载 MySQL架构设计及常见业务处理30套数据库系列Mysql/SQLServer/Redis/Mongodb/Nosql精讲训练营项目实战&#xff0c;数据库设计&#xff0c;架构设计&#xff0c;性能管理&#xff0c;集群搭建&#xff0c;查询优化&#xff0c;索引优化&…

Spring Boot植物健康系统:智慧农业的新趋势

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

经常聊架构模式,设计模式,编程模式,也谈谈“反模式”

在软件工程中&#xff0c;反模式&#xff08;Anti-Pattern&#xff09;是指那些表面上看起来是一个解决方案&#xff0c;但实际上会导致更多问题或者效果不佳的常见实践。它们可能在某些情况下被广泛使用&#xff0c;但实际上是无效甚至产生反效果的。 文档中并没有详细描述具…

四、Prompt工程——简单应用

Prompt工程——简单应用 一、提示工程&#xff08;Prompt Engineering&#xff09;二、Prompt基本法则三、Prompt 调优四、简单的例子文本总结文本判断文本提取文本转化——翻译文本转化——语气 更多结语 一、提示工程&#xff08;Prompt Engineering&#xff09; 提示工程也…

【华为HCIP实战课程二十五】中间到中间系统协议IS-IS配置实战续系统ID区域ID,网络工程师

上章简单讲解了ISIS基本配置,本章继续详细讲解ISIS配置及实施 IS-IS配置拓扑 1、R1进行配置IS-IS [R1]display current-configuration configuration isis isis 1 network-entity 49.0124.1111.1111.1111.00 //配置NET地址,由三部分组成,区域ID、系统ID和固定的SEL 00 i…

python道格拉斯算法的实现

废话不多说 直接开干 需要用到模块 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple math #对浮点数的数学运算函数 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple shapely #提供几何形状的操作和分析&#xff0c;如交集、并集、差集等 pip install -i …

如何保证自动化测试的可信性?

对于自动化测试的可信性&#xff0c;这是一个与自动化测试ROI&#xff08;投资回报率&#xff09;紧密关联的关键问题。自动化测试的可信性&#xff0c;不仅关乎自动化的持续性和价值&#xff0c;更重要的是它是否能够准确、真实地反映产品的质量状态。 举例来说&#xff0c;假…

鸿蒙开发-this指向+样式复用+代码调试

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;鸿蒙开发篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来鸿蒙开发篇专栏内容:鸿蒙开发-this指向样式复用代码调试 目录 一、this指向 1.原生 鸿蒙 this使用细节 -…

windows下使用nvm进行多版本nodejs管理

目录 一&#xff1a;背景 二&#xff1a;nvm的介绍 三&#xff1a;环境切换使用 一&#xff1a;背景 最近在开发node js的项目&#xff0c;其中一个项目的前端和后台使用了两个node版本&#xff0c;因此需要不同的环境配置来进行开发任务&#xff0c;刚好nvm这个插件可以实现…