点击查看更新记录

更新记录

2022-03-21:弹窗样式独立化

  1. 从SAO UTILS WEB 2.0里提取出以前写的弹窗卡片
  2. 新增判断,若没有需要执行的函数方法,只提供一个确认按钮
  3. 新增判断,若存在需要执行的函数方法,提供确认按钮和取消按钮
  4. 修复了布局样式,尽可能让按钮显示对称化
  5. 弹窗文本支持一定程度上的html
点击查看参考教程
参考方向教程原贴
灵感来源:将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,欢迎在评论区进行讨论。

在进行本帖的魔改前,请务必做好备份以便回退。

  1. 新建[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);

    }
  2. 在主题配置文件[blogroot]\_config.butterfly.yml的inject配置项植入js,因为这是类似依赖形式的js,希望它在正文执行前就加载,所以这里我把它在head部分引入。
    inject:
    head:
    - <script src="/js/SAO-Notify.js" async></script>
    bottom:
  3. 然后就可以用以下语法来使用弹窗提示啦:

    <script type="text/javascript">
    SAONotify('Update','欢迎光临!糖果屋上新啦!','location.reload(true);');
    </script>

    又或者在可点击元素里写:

    <button type="button" onclick="SAONotify('Update','欢迎光临!糖果屋上新啦!','location.reload(true);')">刷新按钮</button>
  4. 另外,考虑到有时候是不需要执行方法的,所以也可以忽略第三个执行代码片段的参数。

    <script type="text/javascript">
    SAONotify("secret","旅行者,告诉你个秘密,其实,小青是个......");
    </script>
  5. 那么现在,弹窗功能就独立出来啦,下一篇准备写SAO UI PLAN Controller