更新记录
2022-03-21:弹窗样式独立化
参考方向 | 教程原贴 |
---|---|
灵感来源:将css、dom结构全部放到js里 | dorakika-导航测试 |
参考了弹窗卡片的样式,我参考我自己! | SAO-Utils-Web-2.0 |
预览效果
故事还要从上一篇教程说起,本来嘛,我只是打算写个左右翻页的上下篇UI重写。然后dorakika从我的魔改里得到灵感,写了个悬浮按钮。
然后呢,我从他的悬浮按钮里得到灵感,准备捣鼓个SAO UI风格的控制面板,把现在主题右边的那个侧栏菜单给它捣鼓进控制面板里。
然后灵感一下子就哗啦啦了。
这个时候呢,就想到了我以前写过的SAO UI 风格的右键菜单里,我有专门为了SAO那个无法退出的梗设计了一个退出确认的弹窗彩蛋。然后我就想着,手机的一些操作因为存在误触,那一些误触率高的操作肯定就需要一个弹窗提示,这不,这个弹窗正好可以拿来用。
在剥离的时候已经考虑到了和旧版方案的耦合性,只是借用了css属性,其他的像ID啦,class啦全部都换新了,应该大概,不会出错吧。
借助从dorakika处得到的灵感,因为我只需要在弹窗显示的时候用到样式和dom结构,所以这里设计成直接用js来注入弹窗面板,和以前的NPM插件很像。
SAO UI PLAN 相关项目为本站原创项目,因此均为内测版,在样式适配上仅针对本站进行调整,因此在泛用性上存在缺漏。对于可能遇到的 bug,欢迎在评论区进行讨论。
在进行本帖的魔改前,请务必做好备份以便回退。
新建[Blogroot]\themes\butterfly\source\js\SAO-Notify.js
:
function SAONotify(title,message,action){
// 先移除旧有弹窗,确保不会重叠。
var notifyWindow = document.getElementById('SAO-Notify');
if(notifyWindow){
notifyWindow.remove();
}
//样式文件
var tempstyle = `#SAO-Notify{z-index:9999;background:rgba(204,204,207,0.8);font-family:'SAOUI',Langar,-apple-system,sans-serif;font-weight:bolder;text-shadow:0.5px 0.5px 0.5px#888;height:240px;width:350px;position:fixed;bottom:0;right:0;left:0;top:0;margin:auto auto;border-radius:5px;box-shadow:2px 2px 10px#888;display:block;animation:flashOpen 1s ease alternate}.notify-title{background:rgba(249,249,249,0.8);color:rgba(60,60,61,0.7);height:60px;width:100%;display:block;font-size:20px;text-align:center;border-top-left-radius:5px;border-top-right-radius:5px;padding-top:10px}.notify-alert::-webkit-scrollbar{display:none}.notify-alert{background:rgba(220,220,220,0.8);color:rgba(60,60,61,0.7);height:120px;overflow:scroll;width:100%;display:flex;justify-content:space-around;align-items:center;box-shadow:0px 0px 15px#bcbcbc inset}.notify-button{background:rgba(249,249,249,0.8);height:60px;width:100%;display:block;text-align:center;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding-top:12.5px}.notify-confirm{background:rgba(47,121,212,0);border-radius:50%;display:inline-block;width:36px;height:36px;margin-inline:60px;border:1px solid;border-color:#2f79d4}.notify-confirm button{background:#2f79d4;text-align:center;border-radius:50%;font-size:18px;color:#fff;display:block;width:30px;height:30px;margin:2px}.notify-cancel{background:rgba(203,55,73,0);border-radius:50%;display:inline-block;width:36px;height:36px;margin-inline:60px;border:1px solid;border-color:#cb3749}.notify-cancel button{background:#cb3749;text-align:center;border-radius:50%;font-size:18px;font-weight:bolder;color:#fff;display:block;width:30px;height:30px;margin:2px}.notify-receive{background:rgba(47,121,212,0);border-radius:50%;display:inline-block;width:36px;height:36px;margin-inline:60px;border:1px solid;border-color:#eda60c}.notify-receive button{background:#eda60c;text-align:center;border-radius:50%;font-size:18px;color:#fff;display:block;width:30px;height:30px;margin:2px}@-moz-keyframes flashOpen{from{transform:rotateX(90deg)}to{transform:rotateX(0deg)}}@-webkit-keyframes flashOpen{from{transform:rotateX(90deg)}to{transform:rotateX(0deg)}}@-o-keyframes flashOpen{from{transform:rotateX(90deg)}to{transform:rotateX(0deg)}}@keyframes flashOpen{from{transform:rotateX(90deg)}to{transform:rotateX(0deg)}}@-moz-keyframes flashClose{from{transform:rotateX(0deg)}to{transform:rotateX(90deg)}}@-webkit-keyframes flashClose{from{transform:rotateX(0deg)}to{transform:rotateX(90deg)}}@-o-keyframes flashClose{from{transform:rotateX(0deg)}to{transform:rotateX(90deg)}}@keyframes flashClose{from{transform:rotateX(0deg)}to{transform:rotateX(90deg)}}`;
//若定义了action执行代码片段,则输出有双选项的弹窗
if (action){
var template =`<div id="SAO-Notify"><style>` + tempstyle +`</style><div class="notify-title">` + `${title}` + `</div><div class="notify-alert"> `+ `${message}` + `</div><div class="notify-button"><span class="notify-confirm"><button class="far fa-circle" type="button" name="confirm" onclick="clickAudio();setTimeout(function(){` + `${action}` + `},500);cancelNotify()"></button></span><span class="notify-cancel"><button class="fa fa-times" type="button" name="cancel" onclick="panelAudio();cancelNotify()"></button></span></div><audio id="SAO-Notify-Panel" src="https://npm.elemecdn.com/akilar-candyassets/audio/Panel.mp3"></audio><audio id="SAO-Notify-Click" src="https://npm.elemecdn.com/akilar-candyassets/audio/Click.mp3"></audio>
</div>`
} else { //若未定义action代码片段,则仅输出单选项的弹窗
var template =`<div id="SAO-Notify"><style>` + tempstyle +`</style><div class="notify-title">` + `${title}` + `</div><div class="notify-alert"> `+ `${message}` + `</div><div class="notify-button"><span class="notify-receive"><button class="fas fa-check" type="button" name="receive" onclick="panelAudio();cancelNotify()"></button></span></div><audio id="SAO-Notify-Panel" src="https://npm.elemecdn.com/akilar-candyassets/audio/Panel.mp3"></audio><audio id="SAO-Notify-Click" src="https://npm.elemecdn.com/akilar-candyassets/audio/Click.mp3"></audio>
</div>`
};
document.body.insertAdjacentHTML('beforeend',template);
}
//按钮确认选项音效
function clickAudio() {
var clickAudio = document.getElementById("SAO-Notify-Click");
if (clickAudio) {
clickAudio.play();//有音频时播放
}
}
//按钮取消选项音效
function panelAudio() {
var panelAudio = document.getElementById("SAO-Notify-Panel");
if (panelAudio) {
panelAudio.play();//有音频时播放
}
}
// 关闭通知栏
function cancelNotify(){
var notifyWindow = document.getElementById('SAO-Notify');
notifyWindow.style.animation = 'flashClose 1.5s ease alternate ';
setTimeout(function() {
notifyWindow.remove();
}, 1e3);
}
在主题配置文件[blogroot]\_config.butterfly.yml
的 inject 配置项植入 js,因为这是类似依赖形式的 js,希望它在正文执行前就加载,所以这里我把它在 head 部分引入。
inject:
head:
- <script src="/js/SAO-Notify.js" async></script>
bottom:
然后就可以用以下语法来使用弹窗提示啦:
<script type="text/javascript">
SAONotify('Update','欢迎光临!糖果屋上新啦!','location.reload(true);');
</script>
又或者在可点击元素里写:
<button type="button" onclick="SAONotify('Update','欢迎光临!糖果屋上新啦!','location.reload(true);')">刷新按钮</button>
另外,考虑到有时候是不需要执行方法的,所以也可以忽略第三个执行代码片段的参数。
<script type="text/javascript">
SAONotify("secret","旅行者,告诉你个秘密,其实,小青是个......");
</script>
那么现在,弹窗功能就独立出来啦,下一篇准备写SAO UI PLAN Controller