本文最后更新于:2024年5月7日 下午

在大佬 黑兔小九 看到右键菜单很帅气,照葫芦画瓢在 Fluid 主题做了个低配版,本文记录实现过程。

简介

博客的右键菜单,本质上很简单,就是在当前 Html 界面劫持右键单击事件,禁止默认右键弹出,把自己的右键菜单在当前鼠标位置展示出来。

实现思路

  • 核心技术:自定义网页右键菜单
  • 实现流程:
    • 建立右键菜单:通过 hexo 注入定义,自定义 css 实现样式管理
    • 劫持右键单击事件: js 实现,关闭默认行为,展示自定义的菜单
    • 原始右键功能:为了方便有需要的朋友,将 Ctrl+右键 作为原始右键提供出来
    • 展示提示信息:记录当前右键单击次数,在一定次数时展示提示信息以方便需要使用原始右键菜单的访客

实现过程

建立右键菜单

为了不影响正常数据加载,我决定在 BodyEnd 注入该代码段

source/_inject 文件夹创建 bodyEnd.ejs 文件,在 scripts/page.js 中引入该注入文件:

1
2
3
hexo.extend.filter.register('theme_inject', function(injects) {
injects.bodyEnd.file('default', "source/_inject/bodyEnd.ejs");
});

bodyEnd.ejs 文件写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<div id="tooltip-rightmenu" class="tooltip-rightmenu">如需原始右键菜单请按下 <strong>Ctrl+右键</strong></div>

<div id="rightmenu-wrapper" style="">
<ul class="list-v rightmenu" id="rightmenu-content">
<li class="navigation menuNavigation-Content">
<a class="nav icon-only fix-cursor-default" onclick="history.back()"><i class="iconfont icon-zuojiantou1"></i></a>
<a class="nav icon-only fix-cursor-default" onclick="history.forward()"><i class="iconfont icon-youjiantou1"></i></a>
<a class="nav icon-only fix-cursor-default" onclick="window.location.reload()"><i class="iconfont icon-shuaxin"></i></a>
<a aria-label="TOP" href="#" role="button"><i class="iconfont icon-xiangshang"></i></a>
</li>

<hr class="menuLoad-Content" style="display: block;">
<li class="menuLoad-Content" style="display: block;">
<a class="vlts-menu fix-cursor-default" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
<span>
<i class="iconfont icon-sousuo1 rightmenu-icon"></i>
站内搜索
</span>
</a>
</li>

<li class="menuLoad-Content" style="display: block;">
<a class="vlts-menu fix-cursor-default" href="https://www.zywvvd.com/messagebd/" data-group="link">
<span>
<i class="iconfont icon-yangshi_icon_tongyong_chat rightmenu-icon"> </i>
留言吐槽
</span>
</a>
</li>


<li class="menuLoad-Content" style="display: block;">
<a class="vlts-menu fix-cursor-default" id="help" target="_blank" rel="noopener" href="https://www.foreverblog.cn/go.html" data-group="link">
<span>
<i class="iconfont icon-a-BlackHole rightmenu-icon"></i>
虫洞穿梭
</span>
</a>
</li>

<a id="scroll-top-button" aria-label="TOP" href="#" role="button" style="bottom: 20px; right: 52.6364px;">
<i class="iconfont icon-xiangshangjiantou" aria-hidden="true"></i>
</a>

<hr class="menuLoad-Content" style="display: block;">


</ul>
</div>

<link href="/css/custom.css"type="text/css"rel="stylesheet"/>
<script src="/vvd_js/right_menu.js" type="text/javascript"></script>
<link href="/css/right_menu.css"type="text/css"rel="stylesheet"/>

代码作为示例,事实上需要按照自己需求调整,核心目的是建立右键菜单。

定义右键菜单样式

source/css/custom.css 中添加图标 (我是放在这里的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

@font-face {
font-family: "iconfont"; /* Project id 3859637 */
src: url('//at.alicdn.com/t/c/font_3859637_jxuiuw0et3.woff2?t=1705932159225') format('woff2'),
url('//at.alicdn.com/t/c/font_3859637_jxuiuw0et3.woff?t=1705932159225') format('woff'),
url('//at.alicdn.com/t/c/font_3859637_jxuiuw0et3.ttf?t=1705932159225') format('truetype');
}

.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.icon-xiangshang:before {
content: "\e601";
}

.icon-zuojiantou:before {
content: "\e64e";
}

.icon-xiangshang2:before {
content: "\e76e";
}

.icon-xiangyoujiantou:before {
content: "\e65f";
}

.icon-youjiantou:before {
content: "\e62d";
}

.icon-sousuo1:before {
content: "\e665";
}

.icon-shuaxin:before {
content: "\e6b2";
}

.icon-youjiantou1:before {
content: "\e644";
}

.icon-youjiantou2:before {
content: "\e678";
}

.icon-shuaxin1:before {
content: "\ec08";
}

.icon-zuojiantou1:before {
content: "\e642";
}

.icon-sousuo2:before {
content: "\e612";
}

.icon-zuojiantou2:before {
content: "\e629";
}

.icon-xiangshang1:before {
content: "\e645";
}

.icon-sousuo3:before {
content: "\e6c7";
}

.icon-quanxianfuzhi:before {
content: "\e62b";
}

.icon-icon-1:before {
content: "\e62c";
}

.icon-xiangshangjiantou:before {
content: "\e61f";
}

.icon-liaotianjilu:before {
content: "\e663";
}

.icon-24gf-bubblesDots6:before {
content: "\e95d";
}

.icon-24gf-bubblesDots4:before {
content: "\e95e";
}

.icon-yangshi_icon_tongyong_chat:before {
content: "\e664";
}

.icon-41shuoshuo:before {
content: "\e658";
}

.icon-git:before {
content: "\e799";
}

.icon-duomeit:before {
content: "\e621";
}

.icon-meiti:before {
content: "\e636";
}

.icon-xuniyingpan:before {
content: "\ea6c";
}

.icon-guanyuwomen:before {
content: "\e61e";
}

.icon-dingyue:before {
content: "\e600";
}

.icon-pengyoufill:before {
content: "\e745";
}

.icon-diqiu:before {
content: "\e7b9";
}

.icon-wangzhan:before {
content: "\e628";
}

.icon-chuansong:before {
content: "\e602";
}

.icon-icon-:before {
content: "\e62a";
}

.icon-lianjie:before {
content: "\eadc";
}

.icon-sousuo:before {
content: "\eafe";
}

.icon-jiankong:before {
content: "\eb37";
}

.icon-geren:before {
content: "\e670";
}

.icon-shuji1:before {
content: "\e6b7";
}

.icon-momo:before {
content: "\e8d9";
}

.icon-tongji2:before {
content: "\e61a";
}

.icon-tongjifenxi-xiangmubiaogetongji:before {
content: "\e626";
}

.icon-train1:before {
content: "\e742";
}

.icon-ic_fly:before {
content: "\e6bb";
}

.icon-a-BlackHole:before {
content: "\e95a";
}


source/css/right_menu.css 中定义右键菜单样式:

重点参考 黑兔小九 大佬

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
div#rightmenu-wrapper {
display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
display: none;
position: fixed;
z-index: 2147483648;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}

ul.list-v.rightmenu {
display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
display: block;
background-color: var(--board-bg-color);
max-width: 240px;
overflow: hidden;
}

ul.list-v {
z-index: 1;
display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
display: none;
position: absolute;
background: var(--color-card);
box-shadow: 0 2px 4px 0px rgba(0,0,0,0.08), 0 4px 8px 0px rgba(0,0,0,0.08), 0 8px 16px 0px rgba(0,0,0,0.08);
-webkit-box-shadow: 0 2px 4px 0px rgba(0,0,0,0.08), 0 4px 8px 0px rgba(0,0,0,0.08), 0 8px 16px 0px rgba(0,0,0,0.08);
margin-top: -6px;
border-radius: 4px;
-webkit-border-radius: 4px;
padding: 8px 0;
}


ul.list-v.rightmenu li.navigation, ul.list-v.rightmenu li.music {
display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
display: -ms-flexbox /* TWEENER - IE 10 */;
display: -webkit-flex /* NEW - Chrome */;
display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
display: flex;
justify-content: space-between;
-webkit-justify-content: space-between;
-khtml-justify-content: space-between;
-moz-justify-content: space-between;
-o-justify-content: space-between;
-ms-justify-content: space-between;
}

ul.list-v >li {
white-space: nowrap;
word-break: keep-all;
}


ul.list-v hr {
margin-top: 8px;
margin-bottom: 8px;
}

ul.list-v.rightmenu li.navigation a.nav i, ul.list-v.rightmenu li.music a.nav i {
margin: 0;
width: 32px;
line-height: 32px;
}


ul.list-v >li {
white-space: nowrap;
word-break: keep-all;
}

ul.list-v.rightmenu li.navigation a.nav:first-child, ul.list-v.rightmenu li.music a.nav:first-child {
margin-left: 3px;
}

ul.list-v.rightmenu a.vlts-menu {
text-overflow: ellipsis;
overflow: hidden;
line-height: 36px;
font-weight: normal;
}

.rightmenu-icon{
margin: 0 11px 0 8px;
}



ul.list-v >li>a {
transition: all 0.28s ease;
-webkit-transition: all 0.28s ease;
-khtml-transition: all 0.28s ease;
-moz-transition: all 0.28s ease;
-o-transition: all 0.28s ease;
-ms-transition: all 0.28s ease;
display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
display: block;
color: var(--text-color);
font-size: 1rem;
font-weight: bold;
line-height: 36px;
padding: 0 8px 0 8px;
text-overflow: ellipsis;
margin: 0 4px;
border-radius: 4px;
-webkit-border-radius: 4px;
}

ul.list-v >li>a :hover{
color: var(--link-hover-color)
}


ul.list-v.rightmenu a {
cursor: default;
}


/* 信息提示框 */

.tooltip-rightmenu {
position: fixed;
top: 10%;
left: 50%;
transform: translate(-50%, -50%); /* 居中 */
background: var(--text-color);
color: #fff;
padding: 10px 25px;
border-radius: 5px;
opacity: 0;
z-index: 99;
transition: opacity 1s ease-in-out;
}

.show-tooltip {
opacity: 0.8;
}

js 事件劫持

source/vvd_js 中创建 right_menu.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

var right_cilck_num = 0;
window.oncontextmenu = function(e){
// 检查是否按下了Ctrl键
if (e.ctrlKey) {
return true;
}

e.preventDefault(); //阻止浏览器自带的右键菜单显示
var menu = document.getElementById("rightmenu-wrapper");
menu.style.display = "block"; //将自定义的“右键菜单”显示出来
menu.style.left = e.clientX + "px"; //设置位置,跟随鼠标
menu.style.top = e.clientY+"px";
right_cilck_num = right_cilck_num+ 1;

if(right_cilck_num %7== 1){
const tooltip = document.getElementById('tooltip-rightmenu');
tooltip.classList.add('show-tooltip');

// 3秒后隐藏提示框
setTimeout(() => {
tooltip.classList.remove('show-tooltip');
}, 3000);
}
}
window.onclick = function(e){ //点击窗口,右键菜单隐藏
var menu = document.getElementById("rightmenu-wrapper");
menu.style.display = "none";
}

效果示例

参考资料



文章链接:
https://www.zywvvd.com/notes/hexo/theme/fluid/fluid-custom-rightmenu/fluid-custom-rightmenu/


“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”

微信二维码

微信支付

支付宝二维码

支付宝支付

Fluid -39- 自定义右键菜单
https://www.zywvvd.com/notes/hexo/theme/fluid/fluid-custom-rightmenu/fluid-custom-rightmenu/
作者
Yiwei Zhang
发布于
2024年1月24日
许可协议