实现右键菜单 el-menu,限制在可视范围内

注意点

  • 右键菜单也要记得禁止默认事件
  • 右键的同时保存数据,方便后续使用
  • 右键后对页面添加点击事件,页面点击后隐藏右键菜单
  • 查看右键菜单是相对于整个页面定位,还是相对于某个父元素定位的,因为定位的不同,通过事件对象获取鼠标坐标的方式也不同
    • 相对于页面定位:使用 clientX、clientY(鼠标坐标以浏览器显示区域的左上角开始)
    • 相对于某个父元素定位:使用 layerX、layerY(鼠标坐标以有定位属性的父元素左上角开始)
  • 对鼠标坐标进行判断,限制菜单在可视区域内

效果

 在指定元素右键后,显示右键菜单


html

<div class="g-resources-list">
    <div class="g-resources-item" v-for="item in aResources" :key="item.id"
        :style="{'backgroundColor': item.color}" @contextmenu.prevent="fnResourcesRightClick($event, item)">
        {{item.name}}
    </div>
</div>
<!-- 右键菜单 -->
<div id="rightMenu" v-show="bRightMenuVisible" class="g-menu" @contextmenu.stop.prevent>
    <el-menu @select="fnRightMenuSelect" class="el-menu-vertical" active-text-color="#fff" text-color="#fff">
        <el-menu-item index="1" class="menuItem" title="点击添加">
            <i class="el-icon-folder-add"></i>
            <span slot="title">添加</span>
        </el-menu-item>
        <el-menu-item index="2" class="menuItem" title="点击刷新">
            <i class="el-icon-refresh-right"></i>
            <span slot="title">刷新</span>
        </el-menu-item>
    </el-menu>
</div>

JavaScript

data() {
    return {
        aResources: [{
            id: 1,
            name: '我是资源一',
            color: '#c3d08b'
        }, {
            id: 2,
            name: '我是资源二',
            color: '#f9cc9d'
        }, {
            id: 3,
            name: '我是资源三',
            color: '#fddd9b'
        }], // 资源数据
        bRightMenuVisible: false, // 是否显示右键菜单
        oRightClickItem: null, // 保存右键资源数据,方便后续使用
    }
},
methods: {
    /*
        右键点击资源
        event ==> 事件对象
        item  ==> 资源数据
    */
    fnResourcesRightClick(event, item) {
        // 获取top、left 最大允许像素
        let nScreenWidth = document.documentElement.clientWidth - 98;
        let nScreenHeight = document.documentElement.clientHeight - 54;
        // 菜单显隐
        this.bRightMenuVisible = !this.bRightMenuVisible;
        // 保存右键资源数据,方便后续使用
        this.oRightClickItem = item;
        document.addEventListener("click", () => {
            // 页面点击隐藏菜单
            this.bRightMenuVisible = false;
        });
        
        let oRightMenu = document.querySelector("#rightMenu");
        // 确定菜单位置
        if (event.clientX >= nScreenWidth) {
            // 右键鼠标位置大于最大像素,取最大像素
            oRightMenu.style.left = nScreenWidth + "px";
        } else {
            // 右键鼠标位置小于最大像素,取鼠标位置
            oRightMenu.style.left = event.clientX + "px";
        }
        oRightMenu.style.top =
            (event.clientY >= nScreenHeight ? nScreenHeight : event.clientY) + "px";
    },
    /*
        右键菜单点击
        key ==> 菜单序列
    */
    fnRightMenuSelect(key) {
        key = parseInt(key);
        switch (key) {
            case 1:
                console.log('添加');
                break;
            case 2:
                console.log('刷新');
                break;
        }
    }
}

css

.g-container {
    height: 100vh;
}

.g-resources-list {
    display: flex;
}

.g-resources-list .g-resources-item {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 280px;
}

.g-resources-list .g-resources-item+.g-resources-item {
    margin-left: 10px;
}

/* 右键菜单 -- start */
.g-menu {
    position: absolute;
    width: 96px;
}

.g-menu .el-menu-item {
    display: flex;
    align-items: center;
    width: 96px;
    height: 26px;
    padding: 0 !important;
    line-height: 26px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    transition: all 0.3s;
}

.g-menu .el-menu-item i {
    margin-left: 6px;
}

.g-menu .el-menu-item i.font_family {
    margin: 0 7px 0 9px;
    font-size: 18px;
}

.g-menu .el-menu-item.is-active i {
    color: #909399;
}

.g-menu .el-menu-item:hover {
    background-color: #09aaff;
}

.g-menu .el-menu-item:focus {
    background-color: transparent;
}

.g-menu .el-menu-item:hover i,
.g-menu .el-menu-item:hover span {
    color: #fff;
}

.g-menu .el-menu-item span {
    height: 32px;
    line-height: 35px;
    font-size: 12px;
    text-align: center;
    color: #1a1a1a;
}

.g-menu .el-menu-vertical {
    z-index: 999;
    box-shadow: 0 0.5em 1em 0 rgba(0, 0, 0, 0.2);
    border-radius: 1px;
}

/* 右键菜单 -- end */

参考链接

js鼠标事件 clientX、clientY、offsetX、offsetY、layerX、layerY、pageX、 pageY、screenX、screenY_蒲公英芽的博客-CSDN博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现右键菜单重命名功能,你可以使用el-tree组件的contextmenu事件和自定义右键菜单实现。 首先,在el-tree组件上添加contextmenu事件监听器,可以使用@contextmenu指令或v-contextmenu指令。例如: ```html <el-tree @contextmenu="showContextMenu"> <!-- 树节点内容 --> </el-tree> ``` 接下来,在你的Vue实例中定义showContextMenu方法来处理右键菜单的显示和点击事件。在该方法中,你可以使用event对象的clientX和clientY属性来获取鼠标点击的位置,然后显示自定义的右键菜单。例如: ```javascript methods: { showContextMenu(event) { event.preventDefault(); // 阻止默认右键菜单弹出 const menu = document.getElementById('custom-menu'); // 获取自定义右键菜单元素 menu.style.left = event.clientX + 'px'; // 设置菜单的水平位置 menu.style.top = event.clientY + 'px'; // 设置菜单的垂直位置 menu.style.display = 'block'; // 显示菜单 // 其他逻辑... } } ``` 注意,上述代码中获取自定义右键菜单元素的方式使用了getElementById,所以需要在页面中定义一个id为custom-menu的元素作为自定义右键菜单的容器,并设置其样式为隐藏。例如: ```html <div id="custom-menu" style="display: none;"> <!-- 自定义右键菜单内容 --> </div> ``` 最后,你还需要在自定义右键菜单的内容中添加一个重命名选项,并为其添加点击事件监听器。在点击事件处理函数中,你可以通过获取当前选中的树节点,进行相应的重命名操作。例如: ```html <div id="custom-menu" style="display: none;"> <div @click="renameNode">重命名</div> </div> ``` ```javascript methods: { renameNode() { // 获取当前选中的树节点 const selectedNode = this.$refs.tree.getCurrentNode(); // 执行重命名逻辑... } } ``` 这样,当用户右键点击el-tree的节点时,会触发showContextMenu方法显示自定义右键菜单,点击重命名选项会执行renameNode方法进行重命名操作。你可以根据具体的业务需求,在renameNode方法中实现对节点的重命名逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

忍冬 ⁡⁡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值