JS实现页面右键菜单

JS实现页面右键菜单,第1张

前言

右键菜单也算是前端页面中比较常见的功能了,今天我就带大家完整的实现右键菜单功能。

contextmenu事件

实现右键菜单我们需要用到 oncontextmenu事件,oncontextmenu事件会在用户右击鼠标时触发。

阻止原有菜单

首先,我们将其绑定到window上:window.oncontextmenu

然后,通过event.preventDefault() 方法阻止掉原有的右键菜单,为我们绑定上新的功能做好准备工作。

         window.oncontextmenu = function(e){
            //取消默认的浏览器自带右键
            e.preventDefault();
        }
创建菜单

创建对应菜单的dom结构,并绑定上对应的功能函数:

    
        功能1
        功能2
        功能3
        功能4  > 
            
                功能4-1
                功能4-2
                功能4-3
                功能4-4
            
        
        功能5
    

当然,现在它还是固定的,不能移动。

菜单随鼠标联动

我们将菜单绝对定位,然后利用event的clientX/clientY 属性,将获取的触发点坐标动态赋给菜单的top/left属性,这样菜单就可以跟鼠标联动了。

        const menu=document.getElementById('menu');
        //根据事件对象中鼠标点击的位置,进行定位
        menu.style.left=e.clientX+'px';
        menu.style.top=e.clientY+'px';

现在菜单虽然能跟鼠标联动了,但它现在还不能在默认情况下隐藏。

怎么办?

菜单显隐

很简单,我们先将菜单通过visibility: hidden;隐藏;

        .menu{
            position: absolute;
            top:0px;
            left: 0px;
            background: #fff;
            border: 1px solid #dadce0;
            visibility: hidden;
        }
        .active{
            visibility: visible;
        }

然后再触发 window.oncontextmenu的时候,添加active显示菜单;

     menu.classList.add('active');

现在,菜单功能基本完成了,只需要在 window 上绑定点击事件,然后将active移出,即可隐藏掉菜单;

        //关闭右键菜单
        window.addEventListener('click', function() {
            menu.classList.remove('active');
        })

到此右键菜单功能的基本功能我们就实现了,但它存在溢出的问题。

菜单溢出

菜单溢出就是在页面的边缘触发右键菜单时,由于触发点距离页面边缘距离小于右键菜单的宽度,所产生菜单显示不全的问题。

子菜单溢出

子菜单溢出也是一样的,就是菜单距离页面边缘的距离小于子菜单的宽度时,出现的子菜单显示不全问题。

解决溢出

要解决溢出问题,我们就得先计算一下,menu.style.left最大值;

由图可知:

e.offsetX == window.innerWidth - menu.offsetWidth时,菜单刚好不会溢出,

e.offsetX > window.innerWidth - menu.offsetWidth时,菜单就会溢出;

所以,menu.style.left最大值是window.innerWidth - menu.offsetWidth

即,当e.offsetX >= window.innerWidth - menu.offsetWidth时,menu.style.left = window.innerWidth - menu.offsetWidth ;

e.offsetX < window.innerWidth - menu.offsetWidth时,menu.style.left = e.offsetX

    const menu=document.getElementById('menu');
    let x = e.offsetX;                //触发点到页面窗口左边的距离
    let winWidth = window.innerWidth; //窗口的内部宽度(包括滚动条)
    let menuWidth = menu.offsetWidth; //菜单宽度,高度包含内边距(padding)和边框(border),不包含外边距(margin)
    x = winWidth - menuWidth >= x ? x : winWidth -menuWidth;
    menu.style.left = x +'px';
解决子菜单溢出

解决子菜单溢出也是同理,在此基础上再减去子菜单的宽度即可。

    const submenu=document.getElementById('submenu');
    if(x > (winWidth -menuWidth - submenu.offsetWidth)){
        submenu.style.left = '-200px';
    }else{
        submenu.style.left ='';
        submenu.style.right ='-200px';
    }
最后效果

示例代码



    
    
    
    Document
    


    
        功能1
        功能2
        功能3
        功能4  > 
            
                功能4-1
                功能4-2
                功能4-3
                功能4-4
            
        
        功能5
    
    


到此完整的右键菜单功能我们就实现了

如果大家还有什么其他想法,欢迎在评论区交流!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1297815.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存