前端菜单?本栏目通过对前端菜单问题整理,来做出以下的解答希望对你有所帮助。
本文将讲解 Web 页面如何实现自定义菜单功能。
线上 demo:
核心思路是:注册 contextmenu 事件,取消该事件的默认行为,然后通过 event 对象拿到光标相对视口的坐标位置(event.clientX 和 event.clientY),通过绝对定位的方式,将自己自定义的初始化时不可见的 div 块显示出来。
实现DOM 结构
首先是 DOM 结构。结构依次为:
div.page-view 为注册 contextmenu 事件的元素;div.contextmenu-mask 是遮罩层,遮住整个窗口。它随右键菜单出现而出现,作用是防止用户调出右键菜单后,还可以点击菜单外的按钮。此外还可以添加有透明度的背景色,但这样效果就类似弹窗了。一般来说,都是不设置底色的。div.contextmenu-content 右键菜单的内容。
这里有几个注意点:
首先取消掉点击区域的菜单事件的默认行为。
拿到光标的坐标,为防止菜单部分跑到窗口外,导致被切割,需要对坐标进行调整。对此我们需要再拿到 菜单的宽高、窗口可视区域宽高。
此外为了防止菜单边缘紧贴窗口边缘,效果不美观,需要设置一个 最小 padding 值 参与计算。
被截断的菜单:
紧贴窗口边缘的菜单:
以设置横坐标为例,有:
这里代码的意思是:当预测发现当前光标作为菜单的左侧时,会导致菜单右侧一部分被切割,就以当前坐标作为菜单的右侧,此时的左上角的坐标为光标减去菜单宽度的值。
完整代码为:
隐藏右键菜单没有使用常规的 display: none;,而是改为使用设置了很大值的 left 和 top。这是因为我要实现的是 自适应宽高 的右键菜单。
为此需要动态拿到菜单的宽高,需要用到 Element.getBoundingClientRect() 方法,而这个方法需要元素在 DOM 树中,且为可见元素,才能拿到宽高,否则只能拿到两个 0。
如果你要实现的菜单是手动写死宽度的,高度通过菜单项的数量来计算的,那么隐藏菜单最好的方案是 display: none。

隐藏菜单和点击菜单项
然后就是点击遮罩层,隐藏菜单和遮罩。以及点击菜单项,执行对应的命令
实现自定义菜单的逻辑并不复杂,也就是修改 contextmenu 事件的行为,显示或隐藏自己写的 div。
但里面有些细节需要处理好,才能写出一个没有 bug 的优秀右键菜单。
关于前端菜单的内容到此结束,希望对大家有所帮助。