提示
本文为使用butterfly博客时魔改所写;其他用途仅做参考
写在前面
我这里使用用的图标为阿里图标:i.iconfont.icon-xxx
,你可自行替换类名将其设置为font awesome的图标
为了偷懒,js中还引用了jQuery,请在使用前将其引入或自行将js代码改为原生js
结构
- 首先,想要一个右键菜单,就得向页面中插入一个Dom结构
- 因为是右键唤醒菜单,与页面其他元素无关联,所以可以将此结构直接插入在body下
- 适配于butterfly主题,即新建一个
rightmenu.pug
文件(见下方),位置放在layout文件夹中即可 - 然后在
themes/butterfly/layout/includes/layout.pug
中引入(注意缩进)
doctype html
html(lang=config.language data-theme=theme.display_mode class=htmlClassHideAside)
head
include ./head.pug
body
...
else
include ./404.pug
include ./rightside.pug
!=partial('includes/third-party/search/index', {}, {cache: true})
+ !=partial('includes/dorakika/rightmenu',{}, {cache:true})
include ./additional-js.pug
rightmenu.pug
#rightMenu
.rightMenu-group.rightMenu-small
a.rightMenu-item(href="javascript:window.history.back();")
i.iconfont.icon-back
a.rightMenu-item(href="javascript:window.history.forward();")
i.iconfont.icon-enter
a.rightMenu-item(href="javascript:window.location.reload();")
i.iconfont.icon-chexiao
a.rightMenu-item(href="javascript:rmf.scrollToTop();")
i.iconfont.icon-top
.rightMenu-group.rightMenu-line.hide#menu-text
a.rightMenu-item(href="javascript:rmf.copySelect();")
i.iconfont.icon-copy
span='复制'
.rightMenu-group.rightMenu-line
a.rightMenu-item(href="javascript:rmf.switchDarkMode();")
i.iconfont.icon-DarkTheme
span='昼夜切换'
a.rightMenu-item(href="javascript:rmf.switchReadMode();")
i.iconfont.icon-read
span='阅读模式'
样式
- 现在,结构已经插入,如果此时预览,就会看到一堆文字被插入到页面底部。
- 样式文件没啥说的,学一下css就可以自己修改了。
- 你可以通过
config.yml
中的inject将其引入,也可以通过@import引入到.styl文件中
/* rightMenu */
#rightMenu{
display: none;
position: fixed;
width: 160px;
height: fit-content;
top: 10%;
left: 10%;
background-color: var(--card-bg);
border: 1px solid var(--font-color);
border-radius: 8px;
z-index: 100;
}
#rightMenu .rightMenu-group{
padding: 7px 6px;
}
#rightMenu .rightMenu-group:not(:nth-last-child(1)){
border-bottom: 1px solid var(--font-color);
}
#rightMenu .rightMenu-group.rightMenu-small{
display: flex;
justify-content: space-between;
}
#rightMenu .rightMenu-group .rightMenu-item{
height: 30px;
line-height: 30px;
border-radius: 8px;
transition: 0.3s;
color: var(--font-color);
}
#rightMenu .rightMenu-group.rightMenu-line .rightMenu-item{
display: flex;
height: 40px;
line-height: 40px;
padding: 0 4px;
}
#rightMenu .rightMenu-group .rightMenu-item:hover{
background-color: var(--text-bg-hover);
}
#rightMenu .rightMenu-group .rightMenu-item i{
display: inline-block;
text-align: center;
line-height: 30px;
width: 30px;
height: 30px;
padding: 0 5px;
}
#rightMenu .rightMenu-group .rightMenu-item span{
line-height: 30px;
}
#rightMenu .rightMenu-group.rightMenu-line .rightMenu-item *{
height: 40px;
line-height: 40px;
}
.rightMenu-group.hide{
display: none;
}
脚本
- 首先要实现的就是控制右键菜单的显示与隐藏:这里使用ontextmenu事件唤醒右键菜单,然后当点击事件发生后,关闭右键菜单
- 从上面的pug文件可以看出,是用a标签加上函数调用实现的各功能项
- 于是,就需要在一个全局对象身上定义一些函数来供这些a标签使用了:这里定义一个rmf对象(rightmenu function),来存放一些函数
let rmf = {};
rmf.showRightMenu = function(isTrue, x=0, y=0){
let $rightMenu = $('#rightMenu');
$rightMenu.css('top',x+'px').css('left',y+'px');
if(isTrue){
$rightMenu.show();
}else{
$rightMenu.hide();
}
}
rmf.switchDarkMode = function(){
const nowMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
if (nowMode === 'light') {
activateDarkMode()
saveToLocal.set('theme', 'dark', 2)
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night)
} else {
activateLightMode()
saveToLocal.set('theme', 'light', 2)
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day)
}
// handle some cases
typeof utterancesTheme === 'function' && utterancesTheme()
typeof FB === 'object' && window.loadFBComment()
window.DISQUS && document.getElementById('disqus_thread').children.length && setTimeout(() => window.disqusReset(), 200)
};
rmf.switchReadMode = function(){
const $body = document.body
$body.classList.add('read-mode')
const newEle = document.createElement('button')
newEle.type = 'button'
newEle.className = 'fas fa-sign-out-alt exit-readmode'
$body.appendChild(newEle)
function clickFn () {
$body.classList.remove('read-mode')
newEle.remove()
newEle.removeEventListener('click', clickFn)
}
newEle.addEventListener('click', clickFn)
}
//复制选中文字
rmf.copySelect = function(){
document.execCommand('Copy',false,null);
//这里可以写点东西提示一下 已复制
}
//回到顶部
rmf.scrollToTop = function(){
btf.scrollToDest(0, 500);
}
// 右键菜单事件
if(! (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))){
window.oncontextmenu = function(event){
$('.rightMenu-group.hide').hide();
//如果有文字选中,则显示 文字选中相关的菜单项
if(document.getSelection().toString()){
$('#menu-text').show();
}
let pageX = event.clientX + 10;
let pageY = event.clientY;
let rmWidth = $('#rightMenu').width();
let rmHeight = $('#rightMenu').height();
if(pageX + rmWidth > window.innerWidth){
pageX -= rmWidth+10;
}
if(pageY + rmHeight > window.innerHeight){
pageY -= pageY + rmHeight - window.innerHeight;
}
rmf.showRightMenu(true, pageY, pageX);
return false;
};
window.addEventListener('click',function(){rmf.showRightMenu(false);});
}