点击查看更新记录
更新记录
2021-01-24:内测版v0.07
2021-01-25:内测版v0.14
2021-01-26:内测版v0.21
2021-01-28:内测版v0.37
2021-01-29:正式版v1.0
2021-01-29:正式版v2.0
2021-01-30:正式版v2.1
2021-01-31:正式版v2.2
点击查看参考教程
参考方向 | 教程原贴 |
---|---|
菜单边框风格伪类样式实现方案 | codepen-Pure CSS SAO Menu Thing |
右键菜单显隐逻辑和原生实现方案 | |
UI风格参考,图标、音效资源采集 | SAO Utils |
图标采集 | fontawesome |
pjax适配参考 | |
原生js实现拖拽效果 | js拖拽:简单五步实现元素拖拽功能 |
由于本教程涉及的所有修改对缩进格式等有严格要求,担心自己控制不好的可以直接下载静态资源。参照教程进行修改。
预览效果
来自店长的碎碎念
写一个SAO
风格的右键菜单算是我的一个执念了,但是搜遍全网页找不到网页版的内容,于是我想起来多年前就用过的一款软件SAO Utils,可惜它虽然有完整的菜单逻辑,但是却是基于C语言写的。至多只能参考一些音效。
最后兜兜转转,在魔改博客时看到了Volantis
的右键菜单。学习了一下右键菜单的魔改原理。决定自己来从零开始做一个SAO
风格的右键菜单。
因为这个项目,魔怔了大概半个月,好在那半个月单位工作基本划水。(嘛,总之摸鱼也是为了给大家写好看的魔改教程嘛)一直被二级菜单的显隐逻辑所困扰,因为用到了相对定位,中间有一段元素是空白的,没法在不破坏菜单项显示效果的情况下直接依靠hover实现持续显示二级菜单的效果,最后是用定时函数控制绝对显隐,用hover
控制持续显隐。总算是有了一个相对舒适的显隐体验。
在一开始,因为想到以前一直被一些读者喷右键菜单占用了原生菜单很讨厌(说实话这样的读者也很讨厌)。所以这次在@卓越科技建议下添加了ctrl+右键打开原生右键菜单的功能。然后考虑到菜单界面对手机不友好,干脆对手机不生效了。
在添加音效时,因为直接链接跳转的话,会来不及启动点击音效,所以只能使用超时函数设置了0.5
秒的延迟,给音效播放留点时间。
也正是因为不是依赖于a
标签的超链接,而是使用window.location.href
来实现页面重定向,所以目前对于pjax
的适配还是有些许不好。会在切换页面时打断全局音乐。
不过塞翁失马焉知非福,也正是因为如此,我又添加了自定义脚本的配置项接口。可以让读者自己开发各种各样的脚本来丰富菜单功能啦。
说到底,既然可以自定义脚本了,那应该也可以适配pjax实现无伤跳转才对。唉,果然还是太菜了
总之,这次的项目就先告一段落啦!
米娜桑,Link Start!
既然已经制作完成了右半边的SAO
风格UI
,肯定不可能满足于此的啦。
说起来我当初执意要选择软件工程专业的时候,有个动机就是被刀剑神域里的VRMMO吸引,想着能有一天可以真的体验上这种完全沉浸式的游戏。不过理想和现实还真的是差距鲜明啊。
于是开始尝试制作左半侧的UI
。球形风格还是很好实现的。大概只花了半天摸鱼时间,就基本实现了球形样式UI
和悬停变色效果,得益于之前做右半边的经验,不管是构建主体还是引入图标都是顺风顺水。
然后在追番考古时发现左侧菜单还有一个属性面板的界面。OK,话不多说。继续加。
总的来说,在熟练掌握相对定位的关系以后,适配起来还是很容易的。因为右键菜单是动态出现的,故而我用的都是绝对长度,自然也不会去考虑和窗口整体大小比例自适应的问题。
一开始是在静态页面上写的纯静态效果,依靠hover
动作控制显隐属性。但是这就导致我遇到了一系列问题。relative
定位下,100%
这个概念居然是相对于父元素的,依靠各种偏移量搭建的菜单一下子就乱了套。为了调整各个子菜单,重新捡起了初中数学知识,列了一堆二元方程组,最后还真的让我整出了一套计算公式。不过静态的css
是不支持这种玩法的啦,好在到时候实装时还有pug
和stylus
可以添加计算变量动态调整。小case
啦。
然后左半边菜单就搞定啦,悬停显示效果和动画里那是一模一样啊。开心!
然后,好吧,要把左半边菜单和右半边菜单组装起来。淦!一想到之前为了调整右侧菜单的显隐逻辑付出的血泪我就恨不得吐血三升。网上的参考内容都是针对于子菜单在父级元素内部的情况,那确实可以靠hover
轻松搞定,但是我设置了一堆偏移量和伪类,导致子菜单和父菜单关键的连接轴是个伪类,hover
无效啊喂!。在体验了两天的天下武功唯快不破以后设置了三种逻辑。
一种是全部通过点击来展开子菜单。但是这样子一来每次点击都要记得关闭,用清空已激活项来初始化的话,二级和三级又要写另一套逻辑。Pass
。
一种是依靠悬停加延时消失来控制显隐。虽然也算是靠谱了,但是二级消失连带着三级也消失了,还是得天下武功,唯快不破!把延时消失时间设长,观感又很差。Pass
。
最后一种是被读者点醒的,所以说当局者迷旁观者清啊,既然前两种方案都是半吊子,那把它们组合起来。一级菜单用点击来控制二级菜单显隐,二级菜单用悬停延时来控制三级菜单显隐,那不就没问题了嘛!说起来SAO Utils就是这个显隐逻辑。啊,顿悟的感觉真爽,我感觉我现在起码能烧出十颗舍利子。
显隐逻辑处理好以后,再做边缘判断。为了确保完整可见,要充分考虑每次点击的情况,感觉又回到了初中数学课堂,分类讨论,列算式,化简,emmm,我应该还算对得起我初中的数学老师吧。这时候又想起洪哥之前吐槽的,点击位置和菜单出现位置偏移有点大了。
没办法,那就再加个可以拖动的吧。诶?那我还做边缘判断干啥?
总之,磕磕绊绊的,总算是可以把完整的SAO UI
复现到网页中了。
嗯,再来一次。Link Start
!
点击查看教程正文
新建:
新建:
修改,引入右键菜单网页元素,注意取消了缓存配置,转为完全默认,需要将改为:
新建,控制右键菜单的显隐。此处的脚本引入使用了异步加载。因为全部都是触发类函数,在监听到相应的点击或悬停事件之前不会执行,所以甚至不会有加载完成后执行脚本的那段阻塞时间。
修改,添加CDN配置项和菜单选项:
因为这次的配置逻辑较为繁复,所以参数解释会比较多:
序号 | 参数 | 备选值 | 参数释义 |
---|---|---|---|
0 | enable | true , false | true为开启右键菜单,false为关闭右键菜单 |
1 | ThreeD | true , false | true为开启3D效果,false为关闭3D效果 |
2 | Instructions | true , false | true为开启说明书,false为关闭说明书。默认开启。内附本帖链接,可能的话,希望可以开着帮我做下宣传 |
3 | hoverShow | true , false | true为开启悬停显示,false为关闭悬停显示。默认开启。控制属性栏和三级菜单的悬停显隐。 |
4.1 | music.enable | true , false | true为开启点击音效,false为关闭点击音效 |
4.2 | music.Launcher | Url,音乐文件的相对路径或外链 | 右键点击打开菜单时的音效,留空则使用默认音效 |
4.3 | music.Click | Url,音乐文件的相对路径或外链 | 左键点击菜单选项时的音效,留空则使用默认音效 |
4.4 | music.Alert | Url,音乐文件的相对路径或外链 | 右键点击退出按钮时的音效,留空则使用默认音效 |
4.5 | music.Panel | Url,音乐文件的相对路径或外链 | 左键点击含子菜单的选项时的音效,留空则使用默认音效 |
5 | util_list | 见下文 | 一级菜单选项 |
5.1 | util_list.icon | eg:fa fa-link | 菜单选项图标,使用fontawesome,也可以使用iconfont |
5.2 | util_list.panel | 见下文 | 角色属性面板 |
5.2.1 | util_list.panel.title | Text | 面板标题 |
5.2.2 | util_list.panel.img | Url,图片相对链接或图床绝对链接 | 面板图片,默认使用角色属性面板图 |
5.2.3 | util_list.panel.prop | Html | 面板内容,支持Html语法 |
5.2.4 | util_list.panel.top | Number eg:-150 | 属性面板偏移量,确保面板右侧箭头对着相应的一级菜单,填写数字即可,不需要加单位 |
5.3 | util_list.link | Url | 链接,站内建议使用相对路径,站外需要使用带协议的绝对路径,与action、menu_list互斥,只能填写一个 |
5.4 | util_list.action | Function | 点击动作,详见本帖拓展内容,与link、menu_list互斥,只能填写一个 |
5.5 | util_list.menutop | Number eg:-150 | 二级菜单面板偏移量,确保面板右侧箭头对着相应的一级菜单,填写数字即可,不需要加单位可选,当前偏移量是根据公式计算的,一般都会对齐 |
5.6 | util_list.menu_list | 见下文 | 仅一级菜单支持该配置项 |
5.6.1 | menu_list.name | Text | 菜单选项标题 |
5.6.2 | menu_list.icon | eg:fa fa-link | 菜单选项图标,使用fontawesome,也可以使用iconfont |
5.6.3 | menu_list.link | Url | 链接,站内建议使用相对路径,站外需要使用带协议的绝对路径,与action、child_list互斥,只能填写一个 |
5.6.4 | menu_list.action | Function | 点击动作,详见本帖拓展内容,与link、child_list互斥,只能填写一个 |
5.6.5 | menu_list.childtop | Number eg:-150 | 二级菜单面板偏移量,确保面板右侧箭头对着相应的一级菜单,填写数字即可,不需要加单位。可选,当前偏移量是根据公式计算的,一般都会对齐 |
5.6.6 | menu_list.child_list | 类似于menu_list | 仅二级菜单支持该配置项,其余下辖配置项与menu_list相同 |
5.6.6.1 | child_list.name | Text | 菜单选项标题 |
5.6.6.2 | child_list.icon | eg:fa fa-link | 菜单选项图标,使用fontawesome,也可以使用iconfont |
5.6.6.3 | child_list.link | Url | 链接,站内建议使用相对路径,站外需要使用带协议的绝对路径,与action互斥,只能填写一个 |
5.6.6.4 | child_list.action | Function | 点击动作,详见本帖拓展内容,与link互斥,只能填写一个 |
点击查看脚本拓展内容
糖果屋出品的右键菜单提供了自定义js配置,读者可以通过封装自己的js脚本,直接通过菜单选项调用。以下会分享几个简单示例。更多内容可以自行探索。希望可以启发读者,在评论区留下更多有趣的脚本。
使用方法:在上文的menu_list
或者child_list
配置项的action
填写函数名即可正常调用。注意action
和link
互斥。所以写了action
就不要写link
了
- name: Mirror
icon: fa fa-indent
action: Mirror()
- name: Search
icon: fa fa-search
action: openSearch()
- name: Tidio
icon: fa fa-server
action: openTidio()
功能:针对gitee镜像站和当前站点的同篇文章跳转,记得更改链接。
function Mirror() {
let pathname;
let hostname;
let url;
pathname = window.location.pathname;
hostname = window.location.hostname;
if (hostname === 'akilar.top') {
url = "https://akilar.gitee.io" + pathname;
window.alert("即将前往糖果屋分店?");
window.location.href = url;
}
else if(hostname === 'akilar.gitee.io') {
url = "https://akilar.top" + pathname;
window.alert("正在返回糖果屋本部?!");
window.location.href = url;
}
else {
window.alert("Master,本地调试不需要跳转哦!?");
}
}
功能:打开local-search
搜索按钮(提取自Butterfly源码,其他主题可能不生效)。
function openSearch() {
document.body.style.cssText = 'width: 100%;overflow: hidden'
document.querySelector('#local-search .search-dialog').style.display = 'block'
document.querySelector('#local-search-input input').focus()
btf.fadeIn(document.getElementById('search-mask'), 0.5)
if (!loadFlag) {
search(GLOBAL_CONFIG.localSearch.path)
loadFlag = true
}
// shortcut: ESC
document.addEventListener('keydown', function f (event) {
if (event.code === 'Escape') {
closeSearch()
document.removeEventListener('keydown', f)
}
})
}
功能:打开algolia
搜索按钮(提取自Butterfly源码,其他主题可能不生效)。
function openAlgolia() {
document.body.style.cssText = 'width: 100%;overflow: hidden'
document.querySelector('#algolia-search .search-dialog').style.display = 'block'
document.querySelector('#algolia-search .ais-search-box--input').focus()
btf.fadeIn(document.getElementById('search-mask'), 0.5)
// shortcut: ESC
document.addEventListener('keydown', function f (event) {
if (event.code === 'Escape') {
closeSearch()
document.removeEventListener('keydown', f)
}
})
}
功能:打开Tidio在线聊天界面(提取自Butterfly源码,其他主题可能不生效)
function openTidio() {
window.tidioChatApi.show();window.tidioChatApi.open();
}
功能:若当前页面有评论区,则跳转评论区,若没有,则跳转到留言板页面,评论区的挂载ID和留言板路径可能不一致,请自己根据实际情况替换。
function ToComment(){
var hasComment = document.getElementById('post-comment');
if (hasComment){
window.location.href = '#post-comment'; //如果有评论区就跳转到评论区
}
else{
linkStart('/comments/');//如果没有,就跳转到留言板
//linkStart是本帖的SAO_Menu.js中带的跳转函数,用于pjax适配
}
}
功能:关闭当前页面。既然是SAO
,怎么可以不致敬一下登出键呢?(对无痕窗口不生效,会提示scripts may close only the windows that were opened by them
)
//关闭当前页面
function Logout(){
window.opener=null;
window.open('','_self');
window.close();
}
SAO风格的右键菜单
二级菜单显隐逻辑适配
Ctrl+右键恢复原生菜单
适配pjax,站内跳转不打断全局音乐
补全左侧圆形列表
补全左侧角色属性栏样式
3D显示效果
添加浮动动态动画