【Hexo】美化教程合集 1

  1. 鉴于每个人的根目录名称都不一样,本帖博客根目录一律以[BlogRoot]指代。
  2. 本贴魔改均基于butterfly主题。
  3. 本帖涉及魔改源码的内容,会使用diff代码块标识,复制时请不要忘记删除前面的+、-符号。
  4. 因为.pug.styl以及.yml等对缩进要求较为严格,请尽量不要使用记事本等无法提供语法高亮的文本编辑器进行修改。
  5. 本帖基于Butterfly主题进行魔改方案编写,因此请读者优先掌握Butterfly主题官方文档的内容后再来进行魔改。
  6. 魔改会过程常常引入自定义的css与js文件,方法见【Hexo】添加自定义css和js文件

1 直达底部按钮

点击查看教程

[BlogRoot]\themes\butterfly\layout\includes\rightside.pug做以下修改:

1
2
3
4
5
button#go-up(type="button" title=_p("rightside.back_to_top"))
i.fas.fa-arrow-up

+button#go-down(type="button" title="直达底部" onclick="btf.scrollToDest(document.body.scrollHeight, 500)")
+ i.fas.fa-arrow-down

2 网站恶搞标题

点击查看教程

  1. 新建文件[BlogRoot]\source\js\title.js,写入以下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //动态标题
    var OriginTitile = document.title;
    var titleTime;
    document.addEventListener('visibilitychange', function () {
    if (document.hidden) {
    //离开当前页面时标签显示内容
    document.title = '👀跑哪里去了~';
    clearTimeout(titleTime);
    } else {
    //返回当前页面时标签显示内容
    document.title = '🐖抓到你啦~';
    //两秒后变回正常标题
    titleTime = setTimeout(function () {
    document.title = OriginTitile;
    }, 2000);
    }
    });
  2. 在主题配置文件_config.butterfly.yml引入该文件:

    1
    2
    3
    inject:
    bottom:
    + - <script async src="/js/title.js"></script>
  3. 重启项目:

    1
    hexo cl && hexo s

3 随机壁纸API汇总

点击查看教程

网上可以查到很多随机壁纸的API,但是很多都用不了或者是图片质量比较低,于是今天汇总了一些目前可以用的随机壁纸API,其中列出来的图片质量都是比较高的,可以放心食用,本站随机壁纸API模块用的都是这部分API。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//IMGAPI
https://imgapi.cn/api.php
//如诗 - API
https://api.likepoems.com/
// 必应每日壁纸
let bingDayBg = screen.width <= 768 ? "url(https://bing.img.run/m.php)" : "url(https://bing.img.run/1920x1080.php)";
// 必应历史壁纸
let bingHistoryBg = screen.width <= 768 ? "url(https://bing.img.run/rand_m.php)" : "url(https://bing.img.run/rand.php)";
// EEE.DOG动漫壁纸
let EEEDog = "url(https://api.yimian.xyz/img?type=moe&size=1920x1080)";
// seovx随机美图
let seovx = "url(https://cdn.seovx.com/?mom=302)";
// picsum随机壁纸
let picsum = "url(https://picsum.photos/1920/1080.webp)";
// 博天随机壁纸
let btstu = "url(http://api.btstu.cn/sjbz/?lx=suiji)";
// tuapi动漫壁纸
let tuapi = "url(https://tuapi.eees.cc/api.php?category=dongman)";
// unsplash随机壁纸 https://source.unsplash.com/random/1920x1080/daily (weekly)
let unsplash = "url(https://source.unsplash.com/random/1920x1080/)";

API链接就是引号引着的部分,具体的参数可以到相应官网查看API文档,这部分已经通过测试,到目前为止都是可用的,并且壁纸质量比较高;尤其是必应unsplashpicsum这几个API的图片质量十分高,赶紧给你的网站换上随机壁纸吧!

4 语雀同款链接卡片

点击查看教程

  1. [BlogRoot]\themes\butterfly\scripts\tag 文件夹下面新建 link.js 并粘贴如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* link
* {% link url,title,favicon,desc %}
* {% link 链接,标题,图标,介绍 %}
*/

'use strict'

let defaultIcon = '<svg t="1670307855063" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19066" width="200" height="200"><path d="M504.064 516.608m-384.256 0a384.256 384.256 0 1 0 768.512 0 384.256 384.256 0 1 0-768.512 0Z" fill="#009CF5" p-id="19068"></path><path d="M746.112 270.464L472.448 485.12l63.104 63.104L750.08 274.56c2.304-2.688-1.28-6.144-3.968-4.096z" fill="#FF4C3A" p-id="19069"></path><path d="M262.016 762.752l273.664-214.528-63.104-63.104-214.656 273.536c-2.176 2.688 1.28 6.144 4.096 4.096z" fill="#FFFFFF" p-id="19070"></path><path d="M505.216 155.136c-3.2 0-5.888 2.56-5.888 5.888v53.504c0 3.2 2.56 5.888 5.888 5.888s5.888-2.56 5.888-5.888v-53.504c-0.128-3.2-2.688-5.888-5.888-5.888zM442.368 160.512c-3.2 0.512-5.376 3.584-4.736 6.784l9.344 52.736c0.512 3.2 3.584 5.376 6.784 4.736 3.2-0.512 5.376-3.584 4.736-6.784l-9.344-52.736c-0.512-3.2-3.584-5.376-6.784-4.736zM396.288 234.368c1.152 3.072 4.48 4.608 7.552 3.456 3.072-1.152 4.608-4.48 3.456-7.552l-18.304-50.304c-1.152-3.072-4.48-4.608-7.552-3.456-3.072 1.152-4.608 4.48-3.456 7.552l18.304 50.304zM348.928 257.408c1.664 2.816 5.248 3.712 7.936 2.176s3.712-5.248 2.176-7.936l-26.752-46.336c-1.664-2.816-5.248-3.712-7.936-2.176-2.816 1.664-3.712 5.248-2.176 7.936l26.752 46.336zM306.304 288.256c2.048 2.432 5.76 2.816 8.192 0.768 2.432-2.048 2.816-5.76 0.768-8.192l-34.432-40.96c-2.048-2.432-5.76-2.816-8.192-0.768-2.432 2.048-2.816 5.76-0.768 8.192l34.432 40.96zM269.696 326.144c2.432 2.048 6.144 1.792 8.192-0.768 2.048-2.432 1.792-6.144-0.768-8.192l-40.96-34.432c-2.432-2.048-6.144-1.792-8.192 0.768-2.048 2.432-1.792 6.144 0.768 8.192l40.96 34.432zM193.792 342.912l46.336 26.752c2.816 1.664 6.4 0.64 7.936-2.176 1.664-2.816 0.64-6.4-2.176-8.064L199.552 332.8c-2.816-1.664-6.4-0.64-7.936 2.176-1.664 2.688-0.64 6.272 2.176 7.936zM168.32 399.488l50.304 18.304c3.072 1.152 6.4-0.512 7.552-3.456 1.152-3.072-0.512-6.4-3.456-7.552l-50.304-18.304c-3.072-1.152-6.4 0.512-7.552 3.456-1.152 3.072 0.384 6.4 3.456 7.552zM207.872 457.344l-52.736-9.344c-3.2-0.512-6.272 1.536-6.784 4.736-0.512 3.2 1.536 6.272 4.736 6.784l52.736 9.344c3.2 0.512 6.272-1.536 6.784-4.736 0.512-3.2-1.536-6.272-4.736-6.784zM201.984 509.568H148.48c-3.2 0-5.888 2.56-5.888 5.888 0 3.2 2.56 5.888 5.888 5.888h53.504c3.2 0 5.888-2.56 5.888-5.888 0-3.2-2.56-5.888-5.888-5.888zM205.44 562.176l-52.736 9.344c-3.2 0.512-5.376 3.584-4.736 6.784 0.512 3.2 3.584 5.376 6.784 4.736l52.736-9.344c3.2-0.512 5.376-3.584 4.736-6.784s-3.584-5.248-6.784-4.736zM217.856 613.376l-50.304 18.304c-3.072 1.152-4.608 4.48-3.456 7.552 1.152 3.072 4.48 4.608 7.552 3.456l50.304-18.304c3.072-1.152 4.608-4.48 3.456-7.552-1.152-3.072-4.48-4.608-7.552-3.456zM238.976 661.504l-46.336 26.752c-2.816 1.664-3.712 5.248-2.176 8.064 1.664 2.816 5.248 3.712 8.064 2.176l46.336-26.752c2.816-1.664 3.712-5.248 2.176-8.064-1.664-2.816-5.248-3.712-8.064-2.176zM268.16 705.408l-40.96 34.432c-2.432 2.048-2.816 5.76-0.768 8.192 2.048 2.432 5.76 2.816 8.192 0.768l40.96-34.432c2.432-2.048 2.816-5.76 0.768-8.192-1.92-2.56-5.632-2.816-8.192-0.768zM304.512 743.424l-34.432 40.96c-2.048 2.432-1.792 6.144 0.768 8.192 2.432 2.048 6.144 1.792 8.192-0.768l34.432-40.96c2.048-2.432 1.792-6.144-0.768-8.192-2.304-1.92-6.016-1.664-8.192 0.768zM347.008 774.656l-26.752 46.336c-1.664 2.816-0.64 6.4 2.176 7.936 2.816 1.664 6.4 0.64 8.064-2.176l26.752-46.336c1.664-2.816 0.64-6.4-2.176-7.936-2.816-1.536-6.4-0.64-8.064 2.176zM394.24 798.08l-18.304 50.304c-1.152 3.072 0.512 6.4 3.456 7.552 3.072 1.152 6.4-0.512 7.552-3.456l18.304-50.304c1.152-3.072-0.512-6.4-3.456-7.552-3.072-1.152-6.528 0.384-7.552 3.456zM440.192 872.32c3.2 0.512 6.272-1.536 6.784-4.736l9.344-52.736c0.512-3.2-1.536-6.272-4.736-6.784-3.2-0.512-6.272 1.536-6.784 4.736l-9.344 52.736c-0.64 3.2 1.536 6.272 4.736 6.784zM502.912 878.08c3.2 0 5.888-2.56 5.888-5.888v-53.504c0-3.2-2.56-5.888-5.888-5.888-3.2 0-5.888 2.56-5.888 5.888v53.504c0 3.2 2.688 5.888 5.888 5.888zM549.632 815.232l9.344 52.736c0.512 3.2 3.584 5.376 6.784 4.736 3.2-0.512 5.376-3.584 4.736-6.784l-9.344-52.736c-0.512-3.2-3.584-5.376-6.784-4.736-3.2 0.512-5.248 3.584-4.736 6.784zM600.832 802.816l18.304 50.304c1.152 3.072 4.48 4.608 7.552 3.456 3.072-1.152 4.608-4.48 3.456-7.552L611.84 798.72c-1.152-3.072-4.48-4.608-7.552-3.456-3.072 1.152-4.608 4.48-3.456 7.552zM649.088 781.696l26.752 46.336c1.664 2.816 5.248 3.712 8.064 2.176 2.816-1.664 3.712-5.248 2.176-8.064l-26.88-46.336c-1.664-2.816-5.248-3.712-8.064-2.176-2.816 1.664-3.712 5.248-2.048 8.064zM692.864 752.384l34.432 40.96c2.048 2.432 5.76 2.816 8.192 0.768 2.432-2.048 2.816-5.76 0.768-8.192l-34.432-40.96c-2.048-2.432-5.76-2.816-8.192-0.768-2.56 2.048-2.816 5.76-0.768 8.192zM730.88 716.032l40.96 34.432c2.432 2.048 6.144 1.792 8.192-0.768 2.048-2.432 1.792-6.144-0.768-8.192l-40.96-34.432c-2.432-2.048-6.144-1.792-8.192 0.768-1.92 2.432-1.664 6.144 0.768 8.192zM762.112 673.664l46.336 26.752c2.816 1.664 6.4 0.64 8.064-2.176 1.664-2.816 0.64-6.4-2.176-7.936L768 663.552c-2.816-1.664-6.4-0.64-8.064 2.176-1.536 2.688-0.64 6.272 2.176 7.936zM785.536 626.432l50.304 18.304c3.072 1.152 6.4-0.512 7.552-3.456 1.152-3.072-0.512-6.4-3.456-7.552l-50.304-18.304c-3.072-1.152-6.4 0.512-7.552 3.456-1.152 3.072 0.384 6.4 3.456 7.552zM800.256 575.872l52.736 9.344c3.2 0.512 6.272-1.536 6.784-4.736 0.512-3.2-1.536-6.272-4.736-6.784l-52.736-9.344c-3.2-0.512-6.272 1.536-6.784 4.736-0.512 3.2 1.536 6.272 4.736 6.784zM800.256 517.76c0 3.2 2.56 5.888 5.888 5.888h53.504c3.2 0 5.888-2.56 5.888-5.888 0-3.2-2.56-5.888-5.888-5.888h-53.504c-3.328 0-5.888 2.56-5.888 5.888zM802.688 471.04l52.736-9.344c3.2-0.512 5.376-3.584 4.736-6.784-0.512-3.2-3.584-5.376-6.784-4.736l-52.736 9.344c-3.2 0.512-5.376 3.584-4.736 6.784 0.512 3.2 3.584 5.248 6.784 4.736zM790.272 419.84l50.304-18.304c3.072-1.152 4.608-4.48 3.456-7.552-1.152-3.072-4.48-4.608-7.552-3.456l-50.304 18.304c-3.072 1.152-4.608 4.48-3.456 7.552 1.152 2.944 4.48 4.608 7.552 3.456zM769.152 371.584l46.336-26.752c2.816-1.664 3.712-5.248 2.176-7.936-1.664-2.816-5.248-3.712-8.064-2.176l-46.336 26.752c-2.816 1.664-3.712 5.248-2.176 8.064 1.664 2.688 5.248 3.712 8.064 2.048zM739.84 327.808l40.96-34.432c2.432-2.048 2.816-5.76 0.768-8.192-2.048-2.432-5.76-2.816-8.192-0.768l-40.96 34.432c-2.432 2.048-2.816 5.76-0.768 8.192 2.048 2.56 5.76 2.816 8.192 0.768zM703.488 289.664l34.432-40.96c2.048-2.432 1.792-6.144-0.768-8.192-2.432-2.048-6.144-1.792-8.192 0.768l-34.432 40.96c-2.048 2.432-1.792 6.144 0.768 8.192 2.432 2.048 6.144 1.792 8.192-0.768zM661.12 258.56l26.752-46.336c1.664-2.816 0.64-6.4-2.176-7.936-2.816-1.664-6.4-0.64-8.064 2.176l-26.752 46.336c-1.664 2.816-0.64 6.4 2.176 7.936 2.816 1.536 6.4 0.64 8.064-2.176zM613.888 235.136l18.304-50.304c1.152-3.072-0.512-6.4-3.456-7.552-3.072-1.152-6.4 0.512-7.552 3.456L602.88 231.168c-1.152 3.072 0.512 6.4 3.456 7.552 3.072 1.024 6.4-0.512 7.552-3.584zM556.544 225.152c3.2 0.512 6.272-1.536 6.784-4.736l9.344-52.736c0.512-3.2-1.536-6.272-4.736-6.784-3.2-0.512-6.272 1.536-6.784 4.736l-9.344 52.736c-0.512 3.2 1.536 6.144 4.736 6.784zM273.536 290.432c2.432 2.432 6.528 2.432 8.96 0 2.432-2.432 2.432-6.528 0-8.96l-21.12-21.12c-2.432-2.432-6.528-2.432-8.96 0-2.432 2.432-2.432 6.528 0 8.96l21.12 21.12zM237.824 333.824c2.944 2.048 6.912 1.28 8.832-1.536 2.048-2.944 1.28-6.912-1.536-8.832l-24.448-17.152c-2.944-2.048-6.912-1.28-8.832 1.536s-1.28 6.912 1.536 8.832l24.448 17.152zM183.04 370.176l27.136 12.672c3.2 1.536 7.04 0.128 8.448-3.072 1.536-3.2 0.128-7.04-3.072-8.448l-27.136-12.672c-3.2-1.536-7.04-0.128-8.448 3.072-1.536 3.2-0.128 7.04 3.072 8.448zM194.688 423.68l-28.928-7.68c-3.456-0.896-6.912 1.152-7.808 4.48-0.896 3.456 1.152 6.912 4.48 7.808l28.928 7.68c3.456 0.896 6.912-1.152 7.808-4.48 0.896-3.456-1.152-6.912-4.48-7.808zM183.168 478.72l-29.824-2.56c-3.456-0.256-6.656 2.304-6.912 5.76-0.256 3.456 2.304 6.656 5.76 6.912l29.824 2.56c3.456 0.256 6.656-2.304 6.912-5.76 0.384-3.456-2.176-6.528-5.76-6.912zM181.504 535.04l-29.824 2.56c-3.456 0.256-6.144 3.456-5.76 6.912 0.256 3.456 3.456 6.144 6.912 5.76l29.824-2.56c3.456-0.256 6.144-3.456 5.76-6.912-0.256-3.456-3.328-6.016-6.912-5.76zM191.36 590.72l-28.928 7.68c-3.456 0.896-5.376 4.352-4.48 7.808 0.896 3.456 4.352 5.376 7.808 4.48l28.928-7.68c3.456-0.896 5.376-4.352 4.48-7.808-0.896-3.328-4.352-5.376-7.808-4.48zM207.232 644.224l-27.136 12.672c-3.2 1.536-4.608 5.248-3.072 8.448 1.536 3.2 5.248 4.608 8.448 3.072l27.136-12.672c3.2-1.536 4.608-5.248 3.072-8.448-1.408-3.2-5.248-4.48-8.448-3.072zM233.984 693.888l-24.448 17.152c-2.944 2.048-3.584 6.016-1.536 8.832 2.048 2.944 6.016 3.584 8.832 1.536l24.448-17.152c2.944-2.048 3.584-6.016 1.536-8.832-2.048-2.944-6.016-3.584-8.832-1.536zM310.912 775.552L293.76 800c-2.048 2.944-1.28 6.912 1.536 8.832 2.944 2.048 6.912 1.28 8.832-1.536l17.152-24.448c2.048-2.944 1.28-6.912-1.536-8.832-2.816-2.048-6.912-1.408-8.832 1.536zM349.184 840.704c3.2 1.536 7.04 0.128 8.448-3.072l12.672-27.136c1.536-3.2 0.128-7.04-3.072-8.448-3.2-1.536-7.04-0.128-8.448 3.072l-12.672 27.136c-1.408 3.2-0.128 6.912 3.072 8.448zM407.808 862.72c3.456 0.896 6.912-1.152 7.808-4.48l7.68-28.928c0.896-3.456-1.152-6.912-4.48-7.808-3.456-0.896-6.912 1.152-7.808 4.48l-7.68 28.928c-0.896 3.328 1.152 6.912 4.48 7.808zM469.376 874.112c3.456 0.256 6.656-2.304 6.912-5.76l2.56-29.824c0.256-3.456-2.304-6.656-5.76-6.912-3.456-0.256-6.656 2.304-6.912 5.76l-2.56 29.824c-0.256 3.584 2.304 6.656 5.76 6.912zM522.496 839.168l2.56 29.824c0.256 3.456 3.456 6.144 6.912 5.76 3.456-0.256 6.144-3.456 5.76-6.912l-2.56-29.824c-0.256-3.456-3.456-6.144-6.912-5.76-3.456 0.256-6.016 3.328-5.76 6.912zM578.176 830.976l7.68 28.928c0.896 3.456 4.352 5.376 7.808 4.48 3.456-0.896 5.376-4.352 4.48-7.808l-7.68-28.928c-0.896-3.456-4.352-5.376-7.808-4.48-3.328 0.896-5.376 4.48-4.48 7.808zM631.68 813.312l12.672 27.136c1.536 3.2 5.248 4.608 8.448 3.072 3.2-1.536 4.608-5.248 3.072-8.448l-12.672-27.136c-1.536-3.2-5.248-4.608-8.448-3.072-3.2 1.536-4.48 5.248-3.072 8.448zM681.344 786.688l17.152 24.448c2.048 2.944 6.016 3.584 8.832 1.536 2.944-2.048 3.584-6.016 1.536-8.832l-17.152-24.448c-2.048-2.944-6.016-3.584-8.832-1.536-2.944 1.92-3.584 5.888-1.536 8.832zM725.504 751.744l21.12 21.12c2.432 2.432 6.528 2.432 8.96 0 2.432-2.432 2.432-6.528 0-8.96l-21.12-21.12c-2.432-2.432-6.528-2.432-8.96 0-2.432 2.432-2.432 6.528 0 8.96zM763.008 709.76l24.448 17.152c2.944 2.048 6.912 1.28 8.832-1.536 2.048-2.944 1.28-6.912-1.536-8.832l-24.448-17.152c-2.944-2.048-6.912-1.28-8.832 1.536-2.048 2.816-1.408 6.784 1.536 8.832zM792.576 661.888l27.136 12.672c3.2 1.536 7.04 0.128 8.448-3.072 1.536-3.2 0.128-7.04-3.072-8.448l-27.136-12.672c-3.2-1.536-7.04-0.128-8.448 3.072-1.536 3.2-0.128 6.912 3.072 8.448zM813.44 609.536l28.928 7.68c3.456 0.896 6.912-1.152 7.808-4.48 0.896-3.456-1.152-6.912-4.48-7.808l-28.928-7.68c-3.456-0.896-6.912 1.152-7.808 4.48-0.896 3.456 1.024 6.912 4.48 7.808zM824.832 554.368l29.824 2.56c3.456 0.256 6.656-2.304 6.912-5.76 0.256-3.456-2.304-6.656-5.76-6.912l-29.824-2.56c-3.456-0.256-6.656 2.304-6.912 5.76-0.256 3.584 2.304 6.656 5.76 6.912zM826.624 498.176l29.824-2.56c3.456-0.256 6.144-3.456 5.76-6.912-0.256-3.456-3.456-6.144-6.912-5.76l-29.824 2.56c-3.456 0.256-6.144 3.456-5.76 6.912 0.256 3.456 3.328 6.016 6.912 5.76zM818.432 442.368l28.928-7.68c3.456-0.896 5.376-4.352 4.48-7.808-0.896-3.456-4.352-5.376-7.808-4.48l-28.928 7.68c-3.456 0.896-5.376 4.352-4.48 7.808 0.896 3.456 4.48 5.376 7.808 4.48zM800.768 388.992l27.136-12.672c3.2-1.536 4.608-5.248 3.072-8.448-1.536-3.2-5.248-4.608-8.448-3.072l-27.136 12.672c-3.2 1.536-4.608 5.248-3.072 8.448 1.536 3.072 5.248 4.48 8.448 3.072zM774.144 339.328l24.448-17.152c2.944-2.048 3.584-6.016 1.536-8.832-2.048-2.944-6.016-3.584-8.832-1.536L766.848 328.96c-2.944 2.048-3.584 6.016-1.536 8.832 1.92 2.816 5.888 3.584 8.832 1.536zM697.216 257.664l17.152-24.448c2.048-2.944 1.28-6.912-1.536-8.832-2.944-2.048-6.912-1.28-8.832 1.536l-17.152 24.448c-2.048 2.944-1.28 6.912 1.536 8.832 2.816 2.048 6.784 1.408 8.832-1.536zM658.944 192.512c-3.2-1.536-7.04-0.128-8.448 3.072l-12.672 27.136c-1.536 3.2-0.128 7.04 3.072 8.448 3.2 1.536 7.04 0.128 8.448-3.072l12.672-27.136c1.408-3.2 0-7.04-3.072-8.448zM600.192 170.496c-3.456-0.896-6.912 1.152-7.808 4.48l-7.68 28.928c-0.896 3.456 1.152 6.912 4.48 7.808 3.456 0.896 6.912-1.152 7.808-4.48l7.68-28.928c1.024-3.328-1.024-6.912-4.48-7.808zM534.912 201.6c3.456 0.256 6.656-2.304 6.912-5.76l2.56-29.824c0.256-3.456-2.304-6.656-5.76-6.912-3.456-0.256-6.656 2.304-6.912 5.76l-2.56 29.824c-0.256 3.456 2.304 6.528 5.76 6.912zM476.032 158.464c-3.456 0.256-6.144 3.456-5.76 6.912l2.56 29.824c0.256 3.456 3.456 6.144 6.912 5.76 3.456-0.256 6.144-3.456 5.76-6.912l-2.56-29.824c-0.256-3.456-3.328-6.016-6.912-5.76zM422.144 173.312c-0.896-3.456-4.352-5.376-7.808-4.48-3.456 0.896-5.376 4.352-4.48 7.808l7.68 28.928c0.896 3.456 4.352 5.376 7.808 4.48 3.456-0.896 5.376-4.352 4.48-7.808l-7.68-28.928zM376.448 219.776l-12.672-27.136c-1.536-3.2-5.248-4.608-8.448-3.072-3.2 1.536-4.608 5.248-3.072 8.448L364.8 225.28c1.536 3.2 5.248 4.608 8.448 3.072 3.2-1.536 4.608-5.376 3.2-8.576zM316.416 253.824c2.048 2.944 6.016 3.584 8.832 1.536 2.944-2.048 3.584-6.016 1.536-8.832l-17.152-24.448c-2.048-2.944-6.016-3.584-8.832-1.536-2.944 2.048-3.584 6.016-1.536 8.832l17.152 24.448z" fill="#FFFFFF" p-id="19071"></path></svg>'

function link(args) {
args = args.join(' ').split(',');
// 获取参数
let url = (args[0] || '').trim(),
title = (args[1] || '点击直达链接').trim(),
favicon = (args[2] ? `<img src="${args[2]}" class="no-lightbox">` : defaultIcon).trim(),
desc = (args[3] || '').trim()

return `<a href="${url}" ${url.includes('http')?'target="_blank"':''} title="${title}" referrerPolicy="no-referrer" class="link_card"><div class="link_icon">${favicon}</div><div class="link_content"><div class="link_title">${title}</div>${desc?`<div class="link_desc">${desc}</div>`:''}</div></a>`
}

hexo.extend.tag.register('link', link, { ends: false })
  1. [BlogRoot]\themes\butterfly\source\css\_tags 文件夹下面新建 link.styl 并粘贴如下代码:
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
.link_card
display: flex
margin: 10px 0
color: var(--font-color) !important
text-decoration: none !important
background: var(--reward-pop)
border-radius: 10px
padding: 12px
&:hover
background: #4976f5
color: white !important
.link_icon,.link_content
height: 4rem
.link_icon
img,svg
height: 4rem
width: 4rem
.link_content
margin-left: 1rem
width: calc(100% - 6rem)
overflow: hidden
line-height: 1.5
display: flex
flex-direction: column
justify-content: center
.link_title
font-weight: bold
font-size: 1.2rem
.link_title,.link_desc
word-break: break-all
overflow:hidden
text-overflow: ellipsis
&:not(:has(.link_desc)) .link_title
display:-webkit-box
-webkit-box-orient:vertical
-webkit-line-clamp:2
.link_desc
opacity: .6
.link_desc,&:has(.link_desc) .link_title
white-space: nowrap
  1. 注意:内容不能有英文逗号,不然会出bug
1
2
3
4
5
6
7
8
9
10
11
<!-- 使用html是为了高亮代码,不必在意 -->
<!-- 参数如下: -->
{% link 链接,标题,图标,介绍 %}
<!-- 示例如下: -->
{% link https://blog.leonus.cn/,Leonus,https://blog.leonus.cn/favicon.ico,进一寸有进一寸的欢喜。 %}
<!-- 你也可以什么都不填,将会全部使用默认值,如下: -->
{% card %}
<!-- 你也可以省略部分内容,如下: -->
{% link https://blog.leonus.cn/ %}
<!-- 位置在后面的参数不填的话可以直接省略,但是如果中间的不想填必须留空,如下: -->
{% link https://blog.leonus.cn/,,,进一寸有进一寸的欢喜。 %}
参数 描述 默认值
链接 如果连接中包含http则新标签打开,否则本标签页打开
标题 网站的标题 点击直达链接
图标 网站favicon链接
介绍 网站的description

5 渐变色版权美化

点击查看教程

详见:渐变色版权美化(店长+微调)

  1. 修改[BlogRoot]\themes\butterfly\layout\includes\post\post-copyright.pug,直接复制以下内容替换原文件内容。此处多次用到了三元运算符作为默认项设置,在确保有主题配置文件的默认项的情况下,也可以在相应文章的front-matter中重新定义作者,原文链接,开源许可协议等内容。

    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
    if theme.post_copyright.enable && page.copyright !== false
    - let author = page.copyright_author ? page.copyright_author : config.author
    - let url = page.copyright_url ? page.copyright_url : page.permalink
    - let license = page.license ? page.license : theme.post_copyright.license
    - let license_url = page.license_url ? page.license_url : theme.post_copyright.license_url
    .post-copyright
    .post-copyright__title
    span.post-copyright-info
    h #[=page.title]
    .post-copyright__type
    span.post-copyright-info
    a(href=url_for(url))= theme.post_copyright.decode ? decodeURI(url) : url
    .post-copyright-m
    .post-copyright-m-info
    .post-copyright-a
    h 作者
    .post-copyright-cc-info
    h=author
    .post-copyright-c
    h 发布于
    .post-copyright-cc-info
    h=date(page.date, config.date_format)
    .post-copyright-u
    h 更新于
    .post-copyright-cc-info
    h=date(page.updated, config.date_format)
    .post-copyright-c
    h 许可协议
    .post-copyright-cc-info
    a.icon(rel='noopener' target='_blank' title='Creative Commons' href='https://creativecommons.org/')
    i.fab.fa-creative-commons
    a(rel='noopener' target='_blank' title=license href=url_for(license_url))=license
  2. 修改[BlogRoot]\themes\butterfly\source\css\_layout\post.styl,直接复制以下内容,替换原文件,这个文件就是自己调节样式的。其中,184行是白天模式的背景色,这里默认是我网站的渐变色,大家可以根据自己的喜好调节;253行是夜间模式的发光光圈颜色,大家也可以自行替换成自己喜欢的颜色:

    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
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    beautify()
    headStyle(fontsize)
    padding-left: unit(fontsize + 12, 'px')

    &:before
    margin-left: unit((-(fontsize + 6)), 'px')
    font-size: unit(fontsize, 'px')

    &:hover
    padding-left: unit(fontsize + 18, 'px')

    h1,
    h2,
    h3,
    h4,
    h5,
    h6
    transition: all .2s ease-out

    &:before
    position: absolute
    top: calc(50% - 7px)
    color: $title-prefix-icon-color
    content: $title-prefix-icon
    line-height: 1
    transition: all .2s ease-out
    @extend .fontawesomeIcon

    &:hover
    &:before
    color: $light-blue

    h1
    headStyle(20)

    h2
    headStyle(18)

    h3
    headStyle(16)

    h4
    headStyle(14)

    h5
    headStyle(12)

    h6
    headStyle(12)

    ol,
    ul
    p
    margin: 0 0 8px

    li
    &::marker
    color: $light-blue
    font-weight: 600
    font-size: 1.05em

    &:hover
    &::marker
    color: var(--pseudo-hover)

    ul > li
    list-style-type: circle

    #article-container
    word-wrap: break-word
    overflow-wrap: break-word

    a
    color: $theme-link-color

    &:hover
    text-decoration: underline

    img
    display: block
    margin: 0 auto 20px
    max-width: 100%
    transition: filter 375ms ease-in .2s

    p
    margin: 0 0 16px

    iframe
    margin: 0 0 20px

    if hexo-config('anchor')
    a.headerlink
    &:after
    @extend .fontawesomeIcon
    float: right
    color: var(--headline-presudo)
    content: '\f0c1'
    font-size: .95em
    opacity: 0
    transition: all .3s

    &:hover
    &:after
    color: var(--pseudo-hover)

    h1,
    h2,
    h3,
    h4,
    h5,
    h6
    &:hover
    a.headerlink
    &:after
    opacity: 1

    ol,
    ul
    ol,
    ul
    padding-left: 20px

    li
    margin: 4px 0

    p
    margin: 0 0 8px

    if hexo-config('beautify.enable')
    if hexo-config('beautify.field') == 'site'
    beautify()
    else if hexo-config('beautify.field') == 'post'
    &.post-content
    beautify()

    > :last-child
    margin-bottom: 0 !important

    #post
    .tag_share
    .post-meta
    &__tag-list
    display: inline-block

    &__tags
    display: inline-block
    margin: 8px 8px 8px 0
    padding: 0 12px
    width: fit-content
    border: 1px solid $light-blue
    border-radius: 12px
    color: $light-blue
    font-size: .85em
    transition: all .2s ease-in-out

    &:hover
    background: $light-blue
    color: var(--white)

    .post_share
    display: inline-block
    float: right
    margin: 8px 0
    width: fit-content

    .social-share
    font-size: .85em

    .social-share-icon
    margin: 0 4px
    width: w = 1.85em
    height: w
    font-size: 1.2em
    line-height: w

    .post-copyright
    position: relative
    margin: 40px 0 10px
    padding: 10px 16px
    border: 1px solid var(--light-grey)
    transition: box-shadow .3s ease-in-out
    overflow: hidden
    border-radius: 12px!important
    background: linear-gradient(45deg, #f6d8f5, #c2f1f0, #f0debf);

    &:before
    background var(--heo-post-blockquote-bg)
    position absolute
    right -26px
    top -120px
    content '\f25e'
    font-size 200px
    font-family 'Font Awesome 5 Brands'
    opacity .2

    &:hover
    box-shadow: 0 0 8px 0 rgba(232, 237, 250, .6), 0 2px 4px 0 rgba(232, 237, 250, .5)

    .post-copyright
    &-meta
    color: $light-blue
    font-weight: bold

    &-info
    padding-left: 6px

    a
    text-decoration: none
    word-break: break-word

    &:hover
    text-decoration: none

    .post-copyright-cc-info
    color: $theme-color;

    .post-outdate-notice
    position: relative
    margin: 0 0 20px
    padding: .5em 1.2em
    border-radius: 3px
    background-color: $noticeOutdate-bg
    color: $noticeOutdate-color

    if hexo-config('noticeOutdate.style') == 'flat'
    padding: .5em 1em .5em 2.6em
    border-left: 5px solid $noticeOutdate-border

    &:before
    @extend .fontawesomeIcon
    position: absolute
    top: 50%
    left: .9em
    color: $noticeOutdate-border
    content: '\f071'
    transform: translateY(-50%)

    .ads-wrap
    margin: 40px 0
    .post-copyright-m-info
    .post-copyright-a,
    .post-copyright-c,
    .post-copyright-u
    display inline-block
    width fit-content
    padding 2px 5px
    [data-theme="dark"]
    #post
    .post-copyright
    background #07080a
    text-shadow #bfbeb8 0 0 2px
    border 1px solid rgb(19 18 18 / 35%)
    box-shadow 0 0 5px var(--theme-color)
    animation flashlight 1s linear infinite alternate
    .post-copyright-info
    color #e0e0e4

    #post
    .post-copyright__title
    font-size 22px
    .post-copyright__notice
    font-size 15px
    .post-copyright
    box-shadow 2px 2px 5px
  3. 默认项的配置

    • 作者:[BlogRoot]\_config.yml中的author配置项

      1
      2
      3
      4
      5
      6
      7
      8
      # Site
      title: Akilarの糖果屋
      subtitle: Akilar.top
      description:
      keywords:
      author: Akilar #默认作者
      language: zh-CN
      timezone: ''
    • 许可协议:[BlogRoot]\_config.butterfly.yml中的licenselicense_url配置项

      1
      2
      3
      4
      5
      post_copyright:
      enable: true
      decode: true
      license: CC BY-NC-SA 4.0
      license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/
  4. 页面覆写配置项,修改对应文章的front-matter

    1
    2
    3
    4
    5
    6
    7
    8
    9
    ---
    title: Copyright-beautify # 文章名称
    date: 2021-03-02 13:52:46 # 文章发布日期
    updated: 2023-11-25 12:27:56 # 文章更新日期
    copyright_author: Nesxc # 作者覆写
    copyright_url: https://www.nesxc.com/post/hexocc.html # 原文链接覆写
    license: # 许可协议名称覆写
    license_url: # 许可协议链接覆写
    ---

6 评论表情包放大

点击查看教程

详见:评论表情包放大功能,超实用

其实实现的原理很简单,就是创建一个盒子,将表情包的内容放在盒子里面,然后控制盒子位置和显示隐藏即可。

  1. 新建文件[BlogRoot]\source\js\emoji.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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    // 如果当前页有评论就执行函数
    if (document.getElementById('post-comment')) owoBig();
    // 表情放大
    function owoBig() {
    let flag = 1, // 设置节流阀
    owo_time = '', // 设置计时器
    m = 3; // 设置放大倍数
    // 创建盒子
    let div = document.createElement('div'),
    body = document.querySelector('body');
    // 设置ID
    div.id = 'owo-big';
    // 插入盒子
    body.appendChild(div)

    // 构造observer
    let observer = new MutationObserver(mutations => {

    for (let i = 0; i < mutations.length; i++) {
    let dom = mutations[i].addedNodes,
    owo_body = '';
    if (dom.length == 2 && dom[1].className == 'OwO-body') owo_body = dom[1];
    // 如果需要在评论内容中启用此功能请解除下面的注释
    // else if (dom.length == 1 && dom[0].className == 'tk-comment') owo_body = dom[0];
    else continue;

    // 禁用右键(手机端长按会出现右键菜单,为了体验给禁用掉)
    if (document.body.clientWidth <= 768) owo_body.addEventListener('contextmenu', e => e.preventDefault());
    // 鼠标移入
    owo_body.onmouseover = (e) => {
    if (flag && e.target.tagName == 'IMG') {
    flag = 0;
    // 移入300毫秒后显示盒子
    owo_time = setTimeout(() => {
    let height = e.path[0].clientHeight * m, // 盒子高
    width = e.path[0].clientWidth * m, // 盒子宽
    left = (e.x - e.offsetX) - (width - e.path[0].clientWidth) / 2, // 盒子与屏幕左边距离
    top = e.y - e.offsetY; // 盒子与屏幕顶部距离

    if ((left + width) > body.clientWidth) left -= ((left + width) - body.clientWidth + 10); // 右边缘检测,防止超出屏幕
    if (left < 0) left = 10; // 左边缘检测,防止超出屏幕
    // 设置盒子样式
    div.style.cssText = `display:flex; height:${height}px; width:${width}px; left:${left}px; top:${top}px;`;
    // 在盒子中插入图片
    div.innerHTML = `<img src="${e.target.src}">`
    }, 300);
    }
    };
    // 鼠标移出隐藏盒子
    owo_body.onmouseout = () => { div.style.display = 'none', flag = 1, clearTimeout(owo_time); }
    }

    })
    observer.observe(document.getElementById('post-comment'), { subtree: true, childList: true }) // 监听的 元素 和 配置项
    }
  2. 新建文件[BlogRoot]\source\css\emoji.css,写入如下内容(更推荐全部写在custom.css):

    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
    #owo-big {
    position: fixed;
    align-items: center;
    background-color: rgb(255, 255, 255);
    border: 1px #aaa solid;
    border-radius: 10px;
    z-index: 9999;
    display: none;
    transform: translate(0, -105%);
    overflow: hidden;
    animation: owoIn 0.3s cubic-bezier(0.42, 0, 0.3, 1.11);
    }

    [data-theme=dark] #owo-big {
    background-color: #4a4a4a
    }

    #owo-big img {
    width: 100%;
    }

    /* 动画效果代码由 Heo:https://blog.zhheo.com/ 提供 */
    @keyframes owoIn {
    0% {
    transform: translate(0, -95%);
    opacity: 0;
    }
    100% {
    transform: translate(0, -105%);
    opacity: 1;
    }
    }
  3. 引入cssjs文件,略

  4. 重启项目,略

7 Vue+Element样式弹窗

点击查看教程

详见:Vue+Element样式弹窗

  1. 在主题配置文件[BlogRoot]\_config.butterfly.yml中 引入VueElement相关依赖:

    1
    2
    3
    4
    5
    6
    inject:
    head:
    + - <link rel="stylesheet" href="https://cdn1.tianli0.top/npm/element-ui@2.15.6/packages/theme-chalk/lib/index.css"> # 引入组件库(f12)
    bottom:
    + - <script async src="https://cdn1.tianli0.top/npm/vue@2.6.14/dist/vue.min.js"></script> # 引入VUE(f12)
    + - <script async src="https://cdn1.tianli0.top/npm/element-ui@2.15.6/lib/index.js"></script> # 引入ElementUI(f12)
  2. 在你想要弹出弹窗的js代码中加入如下代码即可触发弹窗:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    new Vue({
    data: function () {
    this.$notify({
    title: "你已被发现😜",
    message: "小伙子,扒源记住要遵循GPL协议!",
    position: 'top-left',
    offset: 50,
    showClose: true,
    type: "warning",
    duration: 5000
    });
    }
    })
    • notify:弹窗类型,可以替换为message(信息提示)和confirm(二次确认提示)

    • title:弹窗标题,可以改为自定义标题

    • message:弹窗信息,可以改为自定义内容

    • position:弹出位置,bottom、top和left、right两两组合

    • offset:偏移量,简单可以理解为与边界的距离

    • showClose:是否显示关闭按钮

    • type:提示类型,可选success/warning/info/error等

    • duration:停留时间,弹出停留至消失的时间,单位ms

      详见:Vue中常用的提示信息

8 按键防抖

点击查看教程

我们的博客按钮非常多,可能你平时并不在意,如果你为f12按钮绑定了一个弹窗,那当你长按f12可能会无限触发弹窗,这就是没有做按键防抖的后果,我们的是静态博客,所以只消耗本地的资源,如果是有后端服务的,频繁触发某个逻辑可能会消耗服务器资源,因此我们必须在前端过滤这些非法操作,不能让其跑到后端!我这里用的是最初等的计时器对象来防抖,原理就是延迟某个时间再触发逻辑(例如300ms),如果这段时间内按键再次按下直接忽略。

  1. 在任意一个js文件引入以下代码(我是在[BlogRoot]\source\js\custom.js引入的),这个js文件的引入最好在前面,否则可能不能及时生效

    1
    2
    3
    4
    5
    6
    7
    // 防抖全局计时器
    let TT = null; //time用来控制事件的触发
    // 防抖函数:fn->逻辑 time->防抖时间
    function debounce(fn, time) {
    if (TT !== null) clearTimeout(TT);
    TT = setTimeout(fn, time);
    }
  2. 将你需要防抖的函数fn()debounce(fn, 300)替代,防抖时间可以自定义,单位为ms,下面就是一个例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 复制提醒
    document.addEventListener("copy", function () {
    debounce(function () {
    new Vue({
    data: function () {
    this.$notify({
    title: "哎嘿!复制成功🍬",
    message: "若要转载最好保留原文链接哦,给你一个大大的赞!",
    position: 'top-left',
    offset: 50,
    showClose: true,
    type: "success",
    duration: 5000
    });
    }
    })
    }, 300);
    })
  3. 在主题配置文件引入以上js文件,具体过程略。这样写全局都是用一个计时器,考虑到我们的博客较为简单,这样做实测是没啥问题了,再也不怕手抖了!

9 夜间模式动画(店长)

点击查看教程

详见:夜间模式动画(店长)

见本站切换样式😋😋😋

  1. 新建[BlogRoot]\themes\butterfly\layout\includes\custom\sun_moon.pug,这部分其实实质上就是一个svg文件,通过js操作它的旋转显隐,淡入淡出实现动画效果。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    svg(aria-hidden='true', style='position:absolute; overflow:hidden; width:0; height:0')
    symbol#icon-sun(viewBox='0 0 1024 1024')
    path(d='M960 512l-128 128v192h-192l-128 128-128-128H192v-192l-128-128 128-128V192h192l128-128 128 128h192v192z', fill='#FFD878', p-id='8420')
    path(d='M736 512a224 224 0 1 0-448 0 224 224 0 1 0 448 0z', fill='#FFE4A9', p-id='8421')
    path(d='M512 109.248L626.752 224H800v173.248L914.752 512 800 626.752V800h-173.248L512 914.752 397.248 800H224v-173.248L109.248 512 224 397.248V224h173.248L512 109.248M512 64l-128 128H192v192l-128 128 128 128v192h192l128 128 128-128h192v-192l128-128-128-128V192h-192l-128-128z', fill='#4D5152', p-id='8422')
    path(d='M512 320c105.888 0 192 86.112 192 192s-86.112 192-192 192-192-86.112-192-192 86.112-192 192-192m0-32a224 224 0 1 0 0 448 224 224 0 0 0 0-448z', fill='#4D5152', p-id='8423')
    symbol#icon-moon(viewBox='0 0 1024 1024')
    path(d='M611.370667 167.082667a445.013333 445.013333 0 0 1-38.4 161.834666 477.824 477.824 0 0 1-244.736 244.394667 445.141333 445.141333 0 0 1-161.109334 38.058667 85.077333 85.077333 0 0 0-65.066666 135.722666A462.08 462.08 0 1 0 747.093333 102.058667a85.077333 85.077333 0 0 0-135.722666 65.024z', fill='#FFB531', p-id='11345')
    path(d='M329.728 274.133333l35.157333-35.157333a21.333333 21.333333 0 1 0-30.165333-30.165333l-35.157333 35.157333-35.114667-35.157333a21.333333 21.333333 0 0 0-30.165333 30.165333l35.114666 35.157333-35.114666 35.157334a21.333333 21.333333 0 1 0 30.165333 30.165333l35.114667-35.157333 35.157333 35.157333a21.333333 21.333333 0 1 0 30.165333-30.165333z', fill='#030835', p-id='11346')
  2. 新建[BlogRoot]\themes\butterfly\source\css\_layout\sun_moon.styl

    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
    .Cuteen_DarkSky,
    .Cuteen_DarkSky:before
    content ''
    position fixed
    left 0
    right 0
    top 0
    bottom 0
    z-index 88888888

    .Cuteen_DarkSky
    background linear-gradient(#feb8b0, #fef9db)
    &:before
    transition 2s ease all
    opacity 0
    background linear-gradient(#4c3f6d, #6c62bb, #93b1ed)

    .DarkMode
    .Cuteen_DarkSky
    &:before
    opacity 1

    .Cuteen_DarkPlanet
    z-index 99999999
    position fixed
    left -50%
    top -50%
    width 200%
    height 200%
    -webkit-animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
    animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
    transform-origin center bottom


    @-webkit-keyframes CuteenPlanetMove {
    0% {
    transform: rotate(0);
    }
    to {
    transform: rotate(360deg);
    }
    }
    @keyframes CuteenPlanetMove {
    0% {
    transform: rotate(0);
    }
    to {
    transform: rotate(360deg);
    }
    }
    .Cuteen_DarkPlanet
    &:after
    position absolute
    left 35%
    top 40%
    width 9.375rem
    height 9.375rem
    border-radius 50%
    content ''
    background linear-gradient(#fefefe, #fffbe8)

    .search
    span
    display none

    .menus_item
    a
    text-decoration none!important
    //按钮相关,对侧栏按钮做过魔改的可以调整这里的数值
    .icon-V
    padding 5px
  3. 新建[BlogRoot]\themes\butterfly\source\js\sun_moon.js,去除了冗余代码,去jquery

    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
    function switchNightMode() {
    document.querySelector('body').insertAdjacentHTML('beforeend', '<div class="Cuteen_DarkSky"><div class="Cuteen_DarkPlanet"></div></div>'),
    setTimeout(function() {
    document.querySelector('body').classList.contains('DarkMode') ? (document.querySelector('body').classList.remove('DarkMode'), localStorage.setItem('isDark', '0'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')) : (document.querySelector('body').classList.add('DarkMode'), localStorage.setItem('isDark', '1'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')),
    setTimeout(function() {
    document.getElementsByClassName('Cuteen_DarkSky')[0].style.transition = 'opacity 3s';
    document.getElementsByClassName('Cuteen_DarkSky')[0].style.opacity = '0';
    setTimeout(function() {
    document.getElementsByClassName('Cuteen_DarkSky')[0].remove();
    }, 1e3);
    }, 2e3)
    })
    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)
    document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')
    } else {
    activateLightMode()
    saveToLocal.set('theme', 'light', 2)
    document.querySelector('body').classList.add('DarkMode'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')
    }
    // handle some cases
    typeof utterancesTheme === 'function' && utterancesTheme()
    typeof FB === 'object' && window.loadFBComment()
    window.DISQUS && document.getElementById('disqus_thread').children.length && setTimeout(() => window.disqusReset(), 200)
    }
  4. 修改[BlogRoot]\themes\butterfly\layout\includes\head.pug,在文件末位加上一行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      //- global config
    !=partial('includes/head/config', {}, {cache: true})

    include ./head/config_site.pug
    include ./head/noscript.pug

    !=fragment_cache('injectHeadJs', function(){return inject_head_js()})

    !=fragment_cache('injectHead', function(){return injectHtml(theme.inject.head)})
    + include ./custom/sun_moon.pug
  5. 修改[BlogRoot]\themes\butterfly\layout\includes\rightside.pug,把原本的昼夜切换按钮替换掉

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      when 'translate'
    if translate.enable
    button#translateLink(type="button" title=_p('rightside.translate_title'))= translate.default
    when 'darkmode'
    if darkmode.enable && darkmode.button
    - button#darkmode(type="button" title=_p('rightside.night_mode_title'))
    - i.fas.fa-adjust
    + a.icon-V.hidden(onclick='switchNightMode()', title=_p('rightside.night_mode_title'))
    + svg(width='25', height='25', viewBox='0 0 1024 1024')
    + use#modeicon(xlink:href='#icon-moon')
  6. 修改[BlogRoot]\_config.butterfly.yml,引入一下js

    1
    2
    3
    inject:
    bottom:
    + - <script async src="/js/sun_moon.js"></script>
  7. 重启项目并切换夜间模式即可看见效果

    1
    hexo cl; hexo s

10 夜间模式切换动画2.0

点击查看教程

逛博客看见别人的切换动画有月亮,而且颜色也很好看,于是一顿f12操作下大概看懂原理,再结合现在的动画改进一下就是了。(注意:在做本魔改前,请先完成店长的夜间模式切换动画,同时最好也要有引入Vue+Element弹窗。本动画是基于店长的样式改进的,加入了弯月,切换到夜间模式是太阳变月亮,切换到白天模式是月亮变太阳,同时背景颜色也改为了我喜欢的。)

  1. 替换原来的[BlogRoot]\themes\butterfly\source\js\sun_moon.js为以下代码,这里主要改进是由原来的after遮罩换为两个元素,再通过定时器来控制各自元素的透明度达到绘制太阳和月亮的目的:

    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
    function switchNightMode() {
    document.querySelector('body').insertAdjacentHTML('beforeend', '<div class="Cuteen_DarkSky"><div class="Cuteen_DarkPlanet"><div id="sun"></div><div id="moon"></div></div></div>'),
    setTimeout(function () {
    document.querySelector('body').classList.contains('DarkMode') ? (document.querySelector('body').classList.remove('DarkMode'), localStorage.setItem('isDark', '0'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')) : (document.querySelector('body').classList.add('DarkMode'), localStorage.setItem('isDark', '1'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')),
    setTimeout(function () {
    document.getElementsByClassName('Cuteen_DarkSky')[0].style.transition = 'opacity 3s';
    document.getElementsByClassName('Cuteen_DarkSky')[0].style.opacity = '0';
    setTimeout(function () {
    document.getElementsByClassName('Cuteen_DarkSky')[0].remove();
    }, 1e3);
    }, 2e3)
    })
    const nowMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
    if (nowMode === 'light') {
    // 先设置太阳月亮透明度
    document.getElementById("sun").style.opacity = "1";
    document.getElementById("moon").style.opacity = "0";
    setTimeout(function () {
    document.getElementById("sun").style.opacity = "0";
    document.getElementById("moon").style.opacity = "1";
    }, 1000);

    activateDarkMode()
    saveToLocal.set('theme', 'dark', 2)
    // GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night)
    document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')
    // 延时弹窗提醒
    setTimeout(() => {
    new Vue({
    data: function () {
    this.$notify({
    title: "关灯啦🌙",
    message: "当前已成功切换至夜间模式!",
    position: 'top-left',
    offset: 50,
    showClose: true,
    type: "success",
    duration: 5000
    });
    }
    })
    }, 2000)
    } else {
    // 先设置太阳月亮透明度
    document.getElementById("sun").style.opacity = "0";
    document.getElementById("moon").style.opacity = "1";
    setTimeout(function () {
    document.getElementById("sun").style.opacity = "1";
    document.getElementById("moon").style.opacity = "0";
    }, 1000);

    activateLightMode()
    saveToLocal.set('theme', 'light', 2)
    document.querySelector('body').classList.add('DarkMode'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')
    setTimeout(() => {
    new Vue({
    data: function () {
    this.$notify({
    title: "开灯啦🌞",
    message: "当前已成功切换至白天模式!",
    position: 'top-left',
    offset: 50,
    showClose: true,
    type: "success",
    duration: 5000
    });
    }
    })
    }, 2000)
    }
    // handle some cases
    typeof utterancesTheme === 'function' && utterancesTheme()
    typeof FB === 'object' && window.loadFBComment()
    window.DISQUS && document.getElementById('disqus_thread').children.length && setTimeout(() => window.disqusReset(), 200)
    }
  2. 替换原来的[BlogRoot]\themes\butterfly\source\css\_layout\sun_moon.styl为以下代码,主要改变是的绘制太阳和月亮的矢量信息,还有背景颜色改进:

    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
    .Cuteen_DarkSky,
    .Cuteen_DarkSky:before
    content ''
    position fixed
    left 0
    right 0
    top 0
    bottom 0
    z-index 88888888

    .Cuteen_DarkSky
    background linear-gradient(to top, #f8cd71 0, #5bfde9 80%)
    &:before
    transition 2s ease all
    opacity 0
    background linear-gradient(to top, #30cfd0 0, #330867 100%)

    .DarkMode
    .Cuteen_DarkSky
    &:before
    opacity 1

    .Cuteen_DarkPlanet
    z-index 99999999
    position fixed
    left -50%
    top -50%
    width 200%
    height 200%
    -webkit-animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
    animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
    transform-origin center bottom


    @-webkit-keyframes CuteenPlanetMove {
    0% {
    transform: rotate(0);
    }
    to {
    transform: rotate(360deg);
    }
    }
    @keyframes CuteenPlanetMove {
    0% {
    transform: rotate(0);
    }
    to {
    transform: rotate(360deg);
    }
    }
    .Cuteen_DarkPlanet
    #sun
    position absolute
    border-radius 100%
    left 44%
    top 30%
    height 6rem
    width 6rem
    background #ffee94
    box-shadow 0 0 40px #ffee94
    // opacity 0

    #moon
    position absolute
    border-radius 100%
    left 44%
    top 30%
    position absolute
    border-radius 100%
    height 6rem
    width 6rem
    box-shadow -1.8em 1.8em 0 0.2em #fff
    // opacity 1

    // &:after
    // position absolute
    // left 42%
    // top 30%
    // width 6rem
    // height 6rem
    // border-radius 50%
    // content ''
    // background #ffef9e
    // box-shadow 0 0 30px #ffef9e

    .search
    span
    display none

    .menus_item
    a
    text-decoration none!important
    //按钮相关,对侧栏按钮做过魔改的可以调整这里的数值
    // .icon-V
    // padding 5px
  3. 重启项目并切换夜间模式即可看到效果:

    1
    hexo cl; hexo s

11 Heo同款loading动画

点击查看教程

详见:Heo同款loading动画

  • 本教程适用于 Butterfly 主题 4.5 以上版本(实测为 4.7.0 版本)
  • 增加了动画页面下有百分比数字加载的效果
  1. 修改 themes/butterfly/layout/includes/loading/fullpage-loading.pug

    下方的图片链接记得换成自己的

    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
    - loading_img = theme.preloader.avatar
    #loading-box(onclick='document.getElementById("loading-box").classList.add("loaded")')
    .loading-bg
    img.loading-img(class='nolazyload' src=loading_img ? url_for(loading_img) : "https://cdn.staticaly.com/gh/HappyLeeCode/IMG@main/img/avatar.webp")
    .loading-image-dot
    #loading-percentage
    | 0%
    script.
    const loadingPercentage = document.getElementById("loading-percentage");
    loadingPercentage.style.color = "black";
    let loadingPercentageTimer = setInterval(function() {
    var progressBar = document.querySelector(".pace-progress");
    if (!progressBar) return
    var currentValue = progressBar.getAttribute("data-progress-text");
    if (currentValue !== loadingPercentage.textContent) {
    loadingPercentage.textContent = currentValue;
    if (currentValue === "100%") {
    clearInterval(loadingPercentageTimer);
    }
    }
    }, 100);
    const preloader = {
    endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
    },
    initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")
    }
    }
    window.addEventListener('load',()=> { preloader.endLoading() })

    if (!{theme.pjax && theme.pjax.enable}) {
    document.addEventListener('pjax:send', () => { preloader.initLoading() })
    document.addEventListener('pjax:complete', () => { preloader.endLoading() })
    }
  2. 修改themes/butterfly/layout/includes/loading/index.pug

    1
    2
    3
    4
    5
    6
    7
    if theme.preloader.source === 1
    include ./fullpage-loading.pug
    else if theme.preloader.source === 2
    include ./pace.pug
    else
    include ./fullpage-loading.pug
    include ./pace.pug
  3. 新建source/css/progress_bar.css, 也可以不做这一步,那么最后一步中修改配置文件pace_css_url这一项就要留空, 这一步是修改 pace 加载的胶囊 💊 样式用的

    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
      .pace {
    -webkit-pointer-events: none;
    pointer-events: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    z-index: 2000;
    position: fixed;
    margin: auto;
    top: 10px;
    left: 0;
    right: 0;
    height: 8px;
    border-radius: 8px;
    width: 4rem;
    background: #eaecf2;
    border: 1px #e3e8f7;
    overflow: hidden;
    }

    .pace-inactive .pace-progress {
    opacity: 0;
    transition: 0.3s ease-in;
    }

    .pace .pace-progress {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    -o-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    max-width: 200px;
    position: absolute;
    z-index: 2000;
    display: block;
    top: 0;
    right: 100%;
    height: 100%;
    width: 100%;
    background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
    animation: gradient 1.5s ease infinite;
    background-size: 200%;
    }

    .pace.pace-inactive {
    opacity: 0;
    transition: 0.3s;
    top: -8px;
    }
    @keyframes gradient {
    0% {
    background-position: 0% 50%;
    }
    50% {
    background-position: 100% 50%;
    }
    100% {
    background-position: 0% 50%;
    }
    }
  4. 修改themes/butterfly/source/css/_layout/loading.styl, 注意其中 .loading-bg 那一项下的 background 可以自行修改为自己的色值。(这里其实就是在修改加载背景的颜色,例如我的颜色是浅蓝色:#B0E2FF)

    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
    if hexo-config('preloader')
    .loading-bg
    display: flex;
    width: 100%;
    height: 100%;
    position: fixed;
    background: #B0E2FF;
    z-index: 1001;
    opacity: 1;
    transition: .3s;

    #loading-box
    .loading-img
    width: 100px;
    height: 100px;
    border-radius: 50%;
    margin: auto;
    border: 4px solid #f0f0f2;
    animation-duration: .3s;
    animation-name: loadingAction;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    .loading-image-dot
    width: 30px;
    height: 30px;
    background: #6bdf8f;
    position: absolute;
    border-radius: 50%;
    border: 6px solid #fff;
    top: 50%;
    left: 50%;
    transform: translate(18px, 24px);
    #loading-percentage
    position: absolute;
    top: 67%;
    left: 50%;
    transform: translateX(-50%);
    &::before
    content: "「"
    margin-right: 10px
    &::after
    content: "」"
    margin-left: 10px
    &.loaded
    .loading-bg
    opacity: 0;
    z-index: -1000;

    @keyframes loadingAction
    0% {
    opacity: 1;
    }

    100% {
    opacity: .4;
    }
  5. [BlogRoot]\source\css\custom.css中添加以下代码,其中 background 的 url 即为 loading 的图片地址。(不会的同学参考 【Hexo】添加自定义css和js文件

    1
    2
    3
    4
    .loading-img {
    background: url(https://cdn.staticaly.com/gh/HappyLeeCode/IMG@main/img/avatar.webp) no-repeat center center;
    background-size: cover;
    }
  6. 最后修改_config.butterfly.ymlpreloader选项, 改完以后source: 1 为满屏加载,无 pace 胶囊;source: 2 为 pace 胶囊,无满屏动画;source: 3 是两者都启用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Loading Animation (加載動畫)
    preloader:
    enable: true
    # source
    # 1. fullpage-loading
    # 2. pace (progress bar)
    source: 3
    # pace theme (see https://codebyzach.github.io/pace/)
    pace_css_url: /css/progress_bar.css

12 自定义右键菜单(自用)

点击查看教程

详见:自定义右键菜单(自用)

右键菜单前置教程:按键防抖(必须)、昼夜切换动画(本站有)、随即文章实现,请完成这两个前置教程再来做这个,或者可以注释掉pug文件中对应的功能就不会出发相应不存在的函数了。

  1. 新建 [BlogRoot]\themes\butterfly\layout\includes\rightmenu.pug,编写以下内容:

    我这里统一采用font-Awesome的图标,因为颜色比较统一,就没用iconfont的图标了

    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
    #rightMenu.js-pjax
    .rightMenu-group.rightMenu-small
    a.rightMenu-item(href="javascript:window.history.back();")
    i.fa.fa-arrow-left
    a.rightMenu-item(href="javascript:window.history.forward();")
    i.fa.fa-arrow-right
    a.rightMenu-item(href="javascript:window.location.reload();")
    i.fa.fa-refresh
    a.rightMenu-item(href="javascript:rmf.scrollToTop();")
    i.fa.fa-arrow-up
    .rightMenu-group.rightMenu-line.hide#menu-text
    a.rightMenu-item(href="javascript:rmf.copySelect();")
    i.fa.fa-copy
    span='复制'
    a.rightMenu-item(href="javascript:window.open(\"https://www.baidu.com/s?wd=\"+window.getSelection().toString());window.location.reload();")
    i.fa.fa-search
    span='百度搜索'
    a.rightMenu-item(href="javascript:rmf.searchinThisPage();")
    i.fas.fa-search
    span='站内搜索'
    .rightMenu-group.rightMenu-line.hide#menu-too
    a.rightMenu-item(href="javascript:window.open(window.getSelection().toString());window.location.reload();")
    i.fa.fa-link
    span='转到链接'
    .rightMenu-group.rightMenu-line.hide#menu-paste
    a.rightMenu-item(href='javascript:rmf.paste()')
    i.fa.fa-copy
    span='粘贴'
    .rightMenu-group.rightMenu-line.hide#menu-post
    a.rightMenu-item(href="#post-comment")
    i.fas.fa-comment
    span='空降评论'
    a.rightMenu-item(href="javascript:rmf.copyWordsLink()")
    i.fa.fa-link
    span='复制本文地址'
    .rightMenu-group.rightMenu-line.hide#menu-to
    a.rightMenu-item(href="javascript:rmf.openWithNewTab()")
    i.fa.fa-window-restore
    span='新窗口打开'
    a.rightMenu-item#menu-too(href="javascript:rmf.open()")
    i.fa.fa-link
    span='转到链接'
    a.rightMenu-item(href="javascript:rmf.copyLink()")
    i.fa.fa-copy
    span='复制链接'
    .rightMenu-group.rightMenu-line.hide#menu-img
    a.rightMenu-item(href="javascript:rmf.saveAs()")
    i.fa.fa-download
    span='保存图片'
    a.rightMenu-item(href="javascript:rmf.openWithNewTab()")
    i.fa.fa-window-restore
    span='在新窗口打开'
    a.rightMenu-item(href="javascript:rmf.copyLink()")
    i.fa.fa-copy
    span='复制图片链接'
    .rightMenu-group.rightMenu-line
    a.rightMenu-item(href="javascript:randomPost()")
    i.fa.fa-paper-plane
    span='随便逛逛'
    a.rightMenu-item(href="javascript:switchNightMode();")
    i.fa.fa-moon
    span='昼夜切换'
    a.rightMenu-item(href="javascript:rmf.translate();")
    i.fa.fa-language
    span='繁简转换'
    if is_post()||is_page()
    a.rightMenu-item(href="javascript:rmf.switchReadMode();")
    i.fa.fa-book
    span='阅读模式'
    a.rightMenu-item(href="/about/")
    i.fa.fa-info-circle
    span='关于博客'
    a.rightMenu-item(href="javascript:toggleWinbox();")
    i.fas.fa-cog
    span='美化设置'
    a.rightMenu-item(href="javascript:rmf.fullScreen();")
    i.fas.fa-expand
    span='切换全屏'
    a.rightMenu-item(href="javascript:window.print();")
    i.fa-solid.fa-print
    span='打印页面'
  2. 然后在 [BlogRoot]/themes/butterfly/layout/includes/layout.pug中引入(注意缩进,去掉+)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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/rightmenu',{}, {cache:true})
    include ./additional-js.pug
  3. 在自定义的custom.css中加入以下样式描述菜单,其中重要的颜色我都做了备注,根据自己的需要修改

    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
    /* 右键菜单 */
    #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;
    }
  4. 创建 [BlogRoot]/themes/butterfly/source/js/rightmenu.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
    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
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    function setMask() {
    //设置遮罩
    if (document.getElementsByClassName("rmMask")[0] != undefined)
    return document.getElementsByClassName("rmMask")[0];
    mask = document.createElement('div');
    mask.className = "rmMask";
    mask.style.width = window.innerWidth + 'px';
    mask.style.height = window.innerHeight + 'px';
    mask.style.background = '#fff';
    mask.style.opacity = '.0';
    mask.style.position = 'fixed';
    mask.style.top = '0';
    mask.style.left = '0';
    mask.style.zIndex = 998;
    document.body.appendChild(mask);
    document.getElementById("rightMenu").style.zIndex = 19198;
    return mask;
    }

    function insertAtCursor(myField, myValue) {

    //IE 浏览器
    if (document.selection) {
    myField.focus();
    sel = document.selection.createRange();
    sel.text = myValue;
    sel.select();
    }

    //FireFox、Chrome等
    else if (myField.selectionStart || myField.selectionStart == '0') {
    var startPos = myField.selectionStart;
    var endPos = myField.selectionEnd;

    // 保存滚动条
    var restoreTop = myField.scrollTop;
    myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);

    if (restoreTop > 0) {
    myField.scrollTop = restoreTop;
    }

    myField.focus();
    myField.selectionStart = startPos + myValue.length;
    myField.selectionEnd = startPos + myValue.length;
    } else {
    myField.value += myValue;
    myField.focus();
    }
    }

    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.copyWordsLink = function () {
    let url = window.location.href
    let txa = document.createElement("textarea");
    txa.value = url;
    document.body.appendChild(txa)
    txa.select();
    document.execCommand("Copy");
    document.body.removeChild(txa);
    }
    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 () {
    document.getElementsByClassName("menus_items")[1].setAttribute("style", "");
    document.getElementById("go-up").setAttribute("style", "display:none");
    btf.scrollToDest(0, 500);
    }
    rmf.translate = function () {
    document.getElementById("translateLink").click();
    }
    rmf.searchinThisPage=()=>{
    document.body.removeChild(mask);
    document.getElementsByClassName("local-search-box--input")[0].value=window.getSelection().toString()
    document.getElementsByClassName("search")[0].click()
    var evt = document.createEvent("HTMLEvents");evt.initEvent("input", false, false);document.getElementsByClassName("local-search-box--input")[0].dispatchEvent(evt);
    }
    document.body.addEventListener('touchmove', function () {

    }, { passive: false });

    function popupMenu() {
    window.oncontextmenu = function (event) {
    // if (event.ctrlKey) return true;

    // 当关掉自定义右键时候直接返回
    if (mouseMode == "off") return true;

    $('.rightMenu-group.hide').hide();
    if (document.getSelection().toString()) {
    $('#menu-text').show();
    }
    if (document.getElementById('post')) {
    $('#menu-post').show();
    } else {
    if (document.getElementById('page')) {
    $('#menu-post').show();
    }
    }
    var el = window.document.body;
    el = event.target;
    var a = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\*\+,;=.]+$/
    if (a.test(window.getSelection().toString()) && el.tagName != "A") {
    $('#menu-too').show()
    }
    if (el.tagName == 'A') {
    $('#menu-to').show()
    rmf.open = function () {
    if (el.href.indexOf("http://") == -1 && el.href.indexOf("https://") == -1 || el.href.indexOf("yisous.xyz") != -1) {
    pjax.loadUrl(el.href)
    }
    else {
    location.href = el.href
    }
    }
    rmf.openWithNewTab = function () {
    window.open(el.href);
    // window.location.reload();
    }
    rmf.copyLink = function () {
    let url = el.href
    let txa = document.createElement("textarea");
    txa.value = url;
    document.body.appendChild(txa)
    txa.select();
    document.execCommand("Copy");
    document.body.removeChild(txa);
    }
    } else if (el.tagName == 'IMG') {
    $('#menu-img').show()
    rmf.openWithNewTab = function () {
    window.open(el.src);
    // window.location.reload();
    }
    rmf.click = function () {
    el.click()
    }
    rmf.copyLink = function () {
    let url = el.src
    let txa = document.createElement("textarea");
    txa.value = url;
    document.body.appendChild(txa)
    txa.select();
    document.execCommand("Copy");
    document.body.removeChild(txa);
    }
    rmf.saveAs = function () {
    var a = document.createElement('a');
    var url = el.src;
    var filename = url.split("/")[-1];
    a.href = url;
    a.download = filename;
    a.click();
    window.URL.revokeObjectURL(url);
    }
    } else if (el.tagName == "TEXTAREA" || el.tagName == "INPUT") {
    $('#menu-paste').show();
    rmf.paste = function () {
    navigator.permissions
    .query({
    name: 'clipboard-read'
    })
    .then(result => {
    if (result.state == 'granted' || result.state == 'prompt') {
    //读取剪贴板
    navigator.clipboard.readText().then(text => {
    console.log(text)
    insertAtCursor(el, text)
    })
    } else {
    Snackbar.show({
    text: '请允许读取剪贴板!',
    pos: 'top-center',
    showAction: false,
    })
    }
    })
    }
    }
    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;
    }
    mask = setMask();
    // 滚动消失的代码和阅读进度有冲突,因此放到readPercent.js里面了
    $(".rightMenu-item").click(() => {
    $('.rmMask').attr('style', 'display: none');
    })
    $(window).resize(() => {
    rmf.showRightMenu(false);
    $('.rmMask').attr('style', 'display: none');
    })
    mask.onclick = () => {
    $('.rmMask').attr('style', 'display: none');
    }
    rmf.showRightMenu(true, pageY, pageX);
    $('.rmMask').attr('style', 'display: flex');
    return false;
    };

    window.addEventListener('click', function () {
    rmf.showRightMenu(false);
    });
    }
    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))) {
    popupMenu()
    }
    const box = document.documentElement

    function addLongtabListener(target, callback) {
    let timer = 0 // 初始化timer

    target.ontouchstart = () => {
    timer = 0 // 重置timer
    timer = setTimeout(() => {
    callback();
    timer = 0
    }, 380) // 超时器能成功执行,说明是长按
    }

    target.ontouchmove = () => {
    clearTimeout(timer) // 如果来到这里,说明是滑动
    timer = 0
    }

    target.ontouchend = () => { // 到这里如果timer有值,说明此触摸时间不足380ms,是点击
    if (timer) {
    clearTimeout(timer)
    }
    }
    }

    addLongtabListener(box, popupMenu)

    // 全屏
    rmf.fullScreen = function () {
    if (document.fullscreenElement) document.exitFullscreen();
    else document.documentElement.requestFullscreen();
    }

    // 右键开关
    if (localStorage.getItem("mouse") == undefined) {
    localStorage.setItem("mouse", "on");
    }
    var mouseMode = localStorage.getItem("mouse");
    function changeMouseMode() {
    if (localStorage.getItem("mouse") == "on") {
    mouseMode = "off";
    localStorage.setItem("mouse", "off");
    debounce(function () {
    new Vue({
    data: function () {
    this.$notify({
    title: "切换右键模式成功🍔",
    message: "当前鼠标右键已恢复为系统默认!",
    position: 'top-left',
    offset: 50,
    showClose: true,
    type: "success",
    duration: 5000
    });
    }
    })
    }, 300);
    } else {
    mouseMode = "on";
    localStorage.setItem("mouse", "on");
    debounce(function () {
    new Vue({
    data: function () {
    this.$notify({
    title: "切换右键模式成功🍔",
    message: "当前鼠标右键已更换为网站指定样式!",
    position: 'top-left',
    offset: 50,
    showClose: true,
    type: "success",
    duration: 5000
    });
    }
    })
    }, 300);
    }
    }
  5. 引入jQuery依赖以及上述的css和js文件(custom.css默认已经引入了就不重复引用了)

    1
    2
    3
    4
    inject:
    bottom:
    + - <script type="text/javascript" src="https://cdn1.tianli0.top/npm/jquery@latest/dist/jquery.min.js"></script>
    + - <script type="text/javascript" src="/js/rightmenu.js"></script>
  6. 本来到这里重启项目就可以见效了,我这里还加了一个右键开关,取消了原来ctrl复合的右键开关策略。因此还需要加一个右键开关的按钮,在[BlogRoot]\themes\butterfly\layout\includes\rightside.pug中做如下的修改,目的就是把鼠标开关放到右边栏的设置隐藏项里面,这样我们就能随时随地开关右键功能了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
          when 'comment'
    if commentsJsLoad
    a#to_comment(href="#post-comment" title=_p("rightside.scroll_to_comment"))
    i.fas.fa-comments

    + when 'mouse'
    + button.share(type="button" title='右键模式' onclick="changeMouseMode()")
    + i.fas.fa-mouse


    #rightside
    - const { enable, hide, show } = theme.rightside_item_order
    - - const hideArray = enable ? hide && hide.split(',') : ['readmode','translate','darkmode']
    + - const hideArray = enable ? hide && hide.split(',') : ['readmode','translate','darkmode','hideAside', 'mouse']
    - const showArray = enable ? show && show.split(',') : ['toc','chat','share','comment']
  7. 重启项目看看效果(可能会有问题,因为这个还是比较复杂的,有问题在评论区留言吧!)

    1
    hexo cl; hexo s