点击查看更新记录

更新记录

2022-03-21:正式版v1.2

  1. 修复云标签侧栏卡片内容出框的问题。

2021-12-16:正式版v1.1

  1. 新增退出蒙版内容。支持点击空白处关闭卡片。
  2. 降级悬浮按钮z-index。打开卡片后,卡片在悬浮按钮上层。

2021-12-14:正式版v1.0

  1. 完成教程编写。正式发布。
  2. 本次更新内容:更难找的加群按钮。
  3. 拜托,要三次点击才能找到的加群按钮,就像小时候搭建的秘密基地一样,超酷的好嘛!

2021-12-09:思路梳理

  1. 完成pug方案改写,可以通过配置文件自由添加按钮。
  2. 移除多宽度适配,开玩笑,我宽度都定死了,去你的自适应
  3. 联动教程:SAO-UI-PLAN-Card-WidgetSAO-UI-PLAN—Card-Player

2021-12-09:思路梳理

  1. 编写思路梳理
  2. 编写TODO

写在最前

是的,还是那片瓜田。

从前,有一天,@贰猹跑来问我能不能写一个仿手机悬浮按钮的功能。那你如果问我能不能,我肯定是回答能的。但你如果问我能不能帮你写,一开始我肯定是选择拒绝的。所以我很干脆的不帮贰猹写啦!

然后就散养了贰猹好几天,还真让他折腾出来了,虽然逻辑很糟糕。但是这个想法确实很有意思啊,虽然逻辑很糟糕。最终的效果贰猹也已经做成了教程,虽然逻辑很糟糕

本来呢,我是不馋贰猹这个功能的,因为我对侧栏卡片很满意,没有贰猹和洪哥那种一定要消灭侧栏的执念。

然而正巧最近我在写侧栏打开评论区的功能的时候,发现在一个微妙的屏幕宽度下,我的侧栏卡片变的超级丑!

那么怎么办呢?贰猹的点子给了我启发,我不想消灭侧栏,因为我舍不得侧栏那些花里胡哨的功能,但是手机端有这个侧栏又确实不是很美观。那么我可以把他们丢进按钮里啊,常态隐藏,点击才显示这样子不就得了。原理嘛,就用fixed定位让他垂直居中,定义最大宽度高度,那么在转为手机端布局的时候,不管是手机还是平板,点开的按钮比例都不会失调。

效果大概长这样子

emm,这个功能,可以搞!

  1. 编写fixed定位下的布局样式,使用单独的class。

  2. 通过js的dom选择,给指定的侧栏按钮添加上述class以实现垂直居中显示

  3. 改写pug源码,修改转为手机端样式时的逻辑,不再是单纯隐藏了事,而是转为隐藏后显示悬浮按钮,可以单独打开。(类似当前的手机端侧栏目录)

  4. 侧栏按钮自定义配置,配置项采用如下形式确保可以让选择器找到对应的卡片元素进行显示。

    1
    2
    3
    4
    5
    - type: class
    name: card_widget
    index: 0
    icon: iconfont icon-author
    title: 作者卡片
  5. 修复各个卡片内自定义布局样式的bug,单独添加到自定义CSS中。给出修复的思路。(看来又是一个不适合做成NPM插件的高耦合方案)

  6. 功能逻辑梳理

魔改步骤

  1. 新建[Blogroot]\themes\butterfly\source\js\custom\fixed_card_widget.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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    // 固定卡片点击动作
    function FixedCardWidget(type,name,index){
    // 根据id或class选择元素
    if (type === "id"){
    var tempcard = document.getElementById(name);
    }
    else{
    var tempcard = document.getElementsByClassName(name)[index];
    }
    // 若元素存在
    if (tempcard) {
    // 首先判断是否存在fixed-card-widget类
    if (tempcard.className.indexOf('fixed-card-widget') > -1){
    // 存在则移除
    RemoveFixedCardWidget();
    }
    else{
    // 不存在则先初始化防止卡片叠加
    RemoveFixedCardWidget();
    //新建退出蒙版
    CreateQuitBox();
    // 再添加固定卡片样式
    tempcard.classList.add('fixed-card-widget');
    }
    }
    }
    //创建一个蒙版,作为退出键使用
    function CreateQuitBox(){
    var quitBox = `<div id="quit-box" onclick="RemoveFixedCardWidget()"></div>`
    var asideContent = document.getElementById('aside-content');
    asideContent.insertAdjacentHTML("beforebegin",quitBox)
    }
    // 移除卡片方法
    function RemoveFixedCardWidget(){
    var activedItems = document.querySelectorAll('.fixed-card-widget');
    if (activedItems) {
    for (i = 0; i < activedItems.length; i++) {
    activedItems[i].classList.remove('fixed-card-widget');
    }
    }
    //移除退出蒙版
    var quitBox = document.getElementById('quit-box');
    if (quitBox) quitBox.remove();
    }
    // 常规先初始化,确保切换页面后不会有固定卡片留存
    RemoveFixedCardWidget()
  2. 新建[Blogroot]\themes\butterfly\source\css\_layout\fixed_card_widget.styl,此处使用stylus交给插件编译,能够更快捷的适配多种内核样式。
    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
    // 垂直居中卡片样式(排除toc目录卡片)
    .fixed-card-widget
    &:not(#card-toc)
    visibility visible!important
    display block!important
    position fixed!important
    bottom 0
    left 0
    top 0
    right 0
    margin auto
    margin-bottom auto!important
    margin-top auto!important
    max-width 300px
    max-height 500px
    width auto
    height auto
    overflow-y: scroll
    z-index 999
    animation rotateX 0.5s ease
    animation-fill-mode forwards
    &::-webkit-scrollbar
    width: 0
    // 针对说说卡片做样式兼容适配
    .card-shuo
    &.fixed-card-widget
    #artitalk_main
    max-height 460px
    overflow scroll
    &::-webkit-scrollbar
    display: none
    #operare_artitalk
    .c2
    z-index 1000
    // 针对标签卡片做样式兼容适配
    .card-tags
    &.fixed-card-widget
    .card-tag-cloud
    max-height 460px
    overflow scroll
    &::-webkit-scrollbar
    display: none
    // 控制手机端可见
    @media screen and (max-width: 768px)
    div#fixedcard-dashboard
    display flex!important
    // 侧栏悬浮按钮样式
    div#fixedcard-dashboard
    position fixed
    top 150px
    width fit-content
    height 40px
    opacity 0.3
    transition all 0.5s
    display none
    background rgba(255,255,255,0.9)
    padding 5px 10px
    border-top-right-radius 20px
    border-bottom-right-radius 20px
    z-index 1000
    &:hover
    opacity 1
    button
    &.fixedcard-activebtn
    width 30px
    opacity 1
    pointer-events all
    // 按钮样式
    button
    &.fixedcard-activebtn
    width 0px
    height 30px
    transition all .5s
    display flex
    opacity 0
    align-items center
    justify-content space-around
    pointer-events none
    color #757273
    // 悬浮按钮头像
    .fixedcard-user-avatar
    display inline-block
    img
    &.fixedcard-user-avatar-img
    width 30px
    height 30px
    border-radius 50%
    // 悬浮按钮夜间模式适配
    [data-theme="dark"]
    div#fixedcard-dashboard
    background rgba(55,55,55,0.9)
    button
    &.fixedcard-activebtn
    color #bcbdbd

    // 卡片开启动画效果
    @keyframes rotateX
    from
    transform rotateX(90deg)
    to
    transform rotateX(0deg)
    // 退出蒙版效果
    div#quit-box
    position fixed
    display block
    left 0
    top 0
    width 100vh
    height 100vh
    z-index 99
    background rgba(25,25,25,0.3)


    [data-theme="dark"]
    div#quit-box
    background rgba(147, 146, 128, 0.3)
  3. 新建[Blogroot]\themes\butterfly\layout\includes\custom\fixed_card_widget.pug,以后的源码魔改教程都会尽量将改动文件归纳到带custom字样的文件夹里,便于管理魔改文件。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #fixedcard-dashboard
    if is_post()
    each poitem in theme.fixed_card_widget.post
    button.fixedcard-activebtn(type="button" title=poitem.title onclick=`FixedCardWidget("` + poitem.type + `","` + poitem.name + `","` + poitem.index + `")`)
    i(class=poitem.icon)
    else
    each paitem in theme.fixed_card_widget.page
    button.fixedcard-activebtn(type="button" title=paitem.title onclick=`FixedCardWidget("` + paitem.type + `","` + paitem.name + `","` + paitem.index + `")`)
    i(class=paitem.icon)
    .fixedcard-user-avatar.fixedcard-activebtn(onclick="RemoveFixedCardWidget()")
    img.fixedcard-user-avatar-img(src=url_for(theme.avatar.img) title=config.author)
  4. 修改[Blogroot]\themes\butterfly\layout\includes\additional-js.pug,直接加在文件末尾即可,但是注意缩进!
    1
    2
    3
    4
      if theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv
    script(async data-pjax src=url_for(theme.CDN.busuanzi))
    + if !theme.aside.mobile && theme.fixed_card_widget.enable
    + include ./custom/fixed_card_widget.pug
  5. 因为还做了page和post页面不同悬浮按钮的配置,为了让它能够自动切换而不是惰性加载,需要修改[Blogroot]\themes\butterfly\layout\includes\third-party\pjax.pug大约第十四行的位置,在pjax选择器中加入悬浮按钮的id。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      script.
    let pjaxSelectors = [
    'title',
    '#config-diff',
    '#body-wrap',
    '#rightside-config-hide',
    '#rightside-config-show',
    + "#fixedcard-dashboard",
    '.js-pjax'
    ]
  6. 修改[Blogroot]\_config.butterfly.yml,新增配置项,此处的选择器其实就是提取了document.getElementsByClassName("name")[index]document.getElementById("name")这两个方法中的参数来确保能够找到侧栏卡片。原本其实是可以做成自动根据侧栏生成的,但是考虑到还有插件挂载和自定义卡片,以及还有部分用户会刻意隐藏一些侧栏卡片,所以干脆还是让用户自己去配置想要加到菜单的卡片好了。
    找id或者class的办法很简单,用F12开启控制台,用左上角的元素选择器点选想要的侧栏卡片,在源码栏找到对应的class或者id。因为class是可以重名的,所以还存在一个序列问题,从0开始计数。此处为了避免语意混乱,建议还是用特征明显的class或者id来选择对应卡片。
    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
    #侧栏悬浮卡片控制按钮
    #https://akilar.top/posts/451ac5f8/
    fixed_card_widget:
    enable: true
    page: #页面显示按钮
    - type: class #侧栏卡片选择器类型
    name: card-info #侧栏卡片选择器名称
    index: 0 #侧栏卡片选择器序列
    icon: fas fa-address-book #图标
    title: 用户信息 #悬停显示提示
    - type: class
    name: card-clock
    index: 0
    icon: fas fa-cloud-sun
    title: 电子钟
    - type: class
    name: card-shuo
    index: 0
    icon: fas fa-comments
    title: 碎碎念
    - type: class
    name: card-recent-post
    index: 0
    icon: fas fa-history
    title: 最新文章
    - type: id
    name: card-newest-comments
    index: 0
    icon: fas fa-comment-dots
    title: 最新评论
    - type: class
    name: card-tags
    index: 0
    icon: fas fa-tags
    title: 标签
    - type: class
    name: card-webinfo
    index: 0
    icon: fas fa-chart-line
    title: 网站咨询
    post: #文章页显示按钮
    - type: class
    name: card-info
    index: 0
    icon: fas fa-address-book
    title: 用户信息
    - type: class
    name: card-clock
    index: 0
    icon: fas fa-cloud-sun
    title: 电子钟
    - type: class
    name: card-recent-post
    index: 0
    icon: fas fa-history
    title: 最新文章
  7. 修改[Blogroot]_config.butterfly.yml的inject配置项

    1
    2
    3
    4
    5
      inject:
    head:

    bottom:
    + - <script data-pjax defer src="/js/custom/fixed_card_widget.js"></script>
  8. 注意要关闭手机端显示侧栏卡片才能启用fixed卡片样式。

    1
    2
    3
    4
    5
    6
    7
      aside:
    enable: true
    hide: false
    button: true
    - mobile: true # display on mobile
    + mobile: false # display on mobile
    position: right # left or right

后日谈

首先要感谢贰猹给我带来的灵感,自打@冰老师神隐以后,感觉博客魔改圈子一下子就沉寂了下来,毕竟每个人都要有自己的生活,为了挣点饭钱,不得不向现实妥协,把生活的大半划分给工作。走出学校以后我也开始渐渐没有时间写博客才怪咧,我每天起码摸两个钟头的鱼,爷就是爱鸽

这次的魔改应该会适合那些想要隐藏某个页面元素又不舍得彻底删除这个元素的傲娇玩家,顺带一提,因为我现在是采用的元素选择来控制卡片显隐,所以,如果你填写的是其他的页面版块,比如页脚#footer,头图#page-header,甚至文章主体#post啥的,也是可以把它们强行拽出来放到固定卡片里的,不过效果会很微妙就是了。

昨天(20211213)@贰猹又说找到了新的灵感,到时候去看看又能带给我什么样的惊喜吧。

TO DO

编写fixed定位布局样式

编写手机端悬浮按钮样式

实现手机端点击按钮显示对应卡片

修改pug,兼容当前的aside显示逻辑