原生JS简易右键菜单

1.效果图

2.kt-contextmenu.js

function createMenu(wrapperId, menuList) {
    if (!wrapperId || !menuList) {
        confirm("请确保入参wrapperId,menuList都存在!");
    }
    if (!Array.isArray(menuList)) {
        confirm("请确保入参menuList的类型为array!");
    }

    const $dest = document.getElementById(wrapperId);// 获取供存储顶级节点
    const currentTime = new Date().getTime();
    const winWidth = document.documentElement.clientWidth || document.body.clientWidth;// 获取菜单显示的位置
    const winHeight = document.documentElement.clientHeight || document.body.clientHeight;

    // 循环菜单JSON
    menuList.forEach(item => {
        // 创建要弹出的菜单节点
        let id = 'menu-' + item.el + '_' + currentTime;
        let oUl = document.createElement('ul');
        oUl.setAttribute('id', id);
        oUl.style.cssText = "font-size: 13px;display: none;width: 130px;border: 1px solid #ccc;position: absolute;box-shadow: 0 0 5px rgba(0, 0, 0, .2);transition: all .1s ease;background-color: #ffffff;"

        item.menu.forEach(menu => {
            let oLi = document.createElement('li');
            oLi.style.cssText = 'display: inline-block;text-align: center;list-style: none;width: 100%;';
            let oA = document.createElement('a');
            oA.style.cssText = 'display: inline-block;text-decoration: none;color: #555;width: 100%;padding: 8px 0;text-align: center;';
            oA.onmouseover = function () {
                this.style.background = '#43a0ff';
                this.style.color = 'white';
            };
            oA.onmouseout = function () {
                this.style.background = 'unset';
                this.style.color = 'unset';
            };
            let textNode = document.createTextNode(menu.text);

            oA.appendChild(textNode);
            oA.onclick = menu.handler;

            oLi.appendChild(oA);
            oUl.appendChild(oLi);
        });

        $dest.appendChild(oUl);

        // 获取要弹出的菜单
        let $menu = document.getElementById(id);
        // 点击其他区域菜单隐藏
        document.addEventListener('click', function () {
            $menu.style.display = 'none';
        });

        // 获取要点击的元素
        let $btn = document.getElementById(item.el);
        // 单击菜单事件
        $btn.onclick = function (event) {
            cleanAllMenu();
            $menu.style.display = 'block';
            let position = getPosition(event, $menu);
            $menu.style.left = position.left + 'px';
            $menu.style.top = position.top + 'px';
            event.stopPropagation();
            return false;
        };
    });

    // 清空所有弹出的菜单
    function cleanAllMenu() {
        menuList.forEach(item => {
            document.getElementById('menu-' + item.el + '_' + currentTime).style.display = 'none';
        })
    }

    // 单击弹出菜单定位
    function getPosition(event, menu) {
        const oEv = event || window.event;
        let l = oEv.clientX, t = oEv.clientY;
        if (l >= (winWidth - menu.offsetWidth)) {
            l = winWidth - menu.offsetWidth;
        }
        if (t > winHeight - menu.offsetHeight) {
            t = winHeight - menu.offsetHeight;
        }
        return {left: l, top: t};
    }
}

3.kt-contextmenu-demo.html

<!doctype html>
<html lang="zh">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="content-type"
          content="text/html;charset=utf-8;X-Content-Type-Options=nosniff;X-XSS-Protection:1;mode=block">
    <meta content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
          name="viewport">
    <meta content="ie=edge" http-equiv="X-UA-Compatible">
    <link href="/web-zhwg-index/common/images/favicon.ico" rel="shortcut icon" type="image/x-icon">
    <link href="/web-zhwg-index/common/css/intelligenceZC.css" rel="stylesheet">
    <title>右键菜单</title>
    <style>
        [v-cloak] {
            display: none !important;
        }

        .el-col {
            height: 200px;
            border: 1px solid red;
            text-align: center;
            line-height: 200px;
            font-size: 30px;
            font-weight: bold;
        }
    </style>
</head>
<body>
<div id="app" v-cloak>
    <el-card style="padding: 20px;" v-cloak>
        <div slot="header">
            KT-CONTEXTMENU-DEMO
        </div>
        <el-row>
            <el-col :span="6" id="one">采集信息</el-col>
            <el-col :span="6" id="two">笔录信息</el-col>
            <el-col :span="6" id="three">现场信息</el-col>
            <el-col :span="6" id="four">技网信息</el-col>
        </el-row>
    </el-card>
</div>
</body>
<script src="/web-zhwg-index/common/util/intelligenceZC.js"></script>
<script src="/web-zhwg-index/components/kt-contextmenu/kt-contextmenu.js"></script>
<script>
    const APP = new Vue({
        el: '#app',
        data() {
            return {
                menuList: [
                    {
                        el: 'one', menu: [
                            {text: `回访信息(0)`, handler: () => this.message("回访信息")},
                            {text: `涉案视图(0)`, handler: () => this.message("涉案视图")},
                            {text: `案件标签(0)`, handler: () => this.message("案件标签")}
                        ]
                    },
                    {
                        el: 'two', menu: [
                            {text: `询问笔录(0)`, handler: () => this.message("询问笔录")},
                            {text: `辨认笔录(0)`, handler: () => this.message("辨认笔录")},
                        ]
                    },
                    {
                        el: 'three', menu: [
                            {text: `手印痕迹(0)`, handler: () => this.message("手印痕迹")},
                            {text: `足迹痕迹(0)`, handler: () => this.message("足迹痕迹")},
                            {text: `工具痕迹(0)`, handler: () => this.message("工具痕迹")},
                            {text: `电子物证(0)`, handler: () => this.message("电子物证")},
                        ]
                    },
                    {
                        el: 'four', menu: [
                            {text: `技侦结果(0)`, handler: () => this.message("技侦结果")},
                            {text: `网安结果(0)`, handler: () => this.message("网安结果")},
                        ]
                    }
                ],
            }
        },
        mounted(){
            createMenu('app', this.menuList);
        }
    })
</script>
</html>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhengvipin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值