简单记录一下我Butterfly主题的美化和魔改

前言

大部分教程都需要在主题配置文件中创建并引入css或者js文件,所以这里先说明一下怎么引入

打开_config.butterfly.yml文件,找到Inject部分,这里以custom.cssdiytitle.js为例,注意这两个都为本地文件,在线网址也一样,更改href=src=里面的内容就行

1
2
3
4
5
6
7
inject:
head:
# - <link rel="stylesheet" href="/xxx.css">
- <link rel="stylesheet" href="/css/custom.css">
bottom:
# - <script src="xxxx"></script>
- <script async src="/js/diytitle.js"></script>

可以将所有的代码都复制到一个 css/js 文件,也可以每做一个修改都建立一个新的 css/js 文件

背景美化

背景一图流

查看步骤
  1. 设置背景

    这个是 Butterfly 自带的功能,修改主题的配置文件 _config.butterfly.yml

    编辑 index_imgbackgroundfooter_bg 选项。

    设置网站背景,并将主页顶部图和页脚背景改为透明。(需要将以下示例地址替换为自己的图片地址。可以用一张具体的图片,也可以用随机图api,随机显示图片)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # Image (圖片設置)
    # --------------------------------------

    # The banner image of home page
    index_img: transparent

    # Beautify/Effect (美化/效果)
    # --------------------------------------

    # Website Background (設置網站背景)
    # can set it to color or image (可設置圖片 或者 顔色)
    # The formal of image: url(http://xxxxxx.com/xxx.jpg)
    background: url(http://xxxxxx.com/xxx.jpg)

    # Footer Background
    footer_bg: transparent
  2. 引入相关样式

    新建一个文件,位于 source/css/modify.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
    @import 'nib'

    // 顶部图
    #page-header
    &, &:before
    background: transparent !important
    &.post-bg, &.not-home-page
    height: 280px !important
    #post-info
    bottom: 40px !important
    #page-site-info
    top: 140px !important

    @media screen and (max-width: 768px)
    &.not-home-page
    height: 200px !important
    #post-info
    bottom: 10px !important
    #page-site-info
    top: 100px !important

    .top-img
    height: 250px
    margin: -50px -40px 50px
    border-top-left-radius: inherit
    border-top-right-radius: inherit
    background-position: center center
    background-size: cover
    transition: all 0.3s

    @media screen and (max-width: 768px)
    height: 230px
    margin: -36px -14px 36px

    [data-theme='dark'] &
    filter: brightness(0.8)

    // 页脚
    #footer:before
    background-color: alpha(#FFF, .5)

    [data-theme='dark'] &
    background-color: alpha(#000, .5)

    #footer-wrap, #footer-wrap a
    color: #111
    transition: unset

    [data-theme='dark'] &
    color: var(--light-grey)

    在主题配置文件 _config.butterfly.ymlinject.head 引入样式。

    1
    2
    3
    4
    5
    6
    # Inject
    # Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
    # 插入代码到头部 </head> 之前 和 底部 </body> 之前
    inject:
    head:
    - <link rel="stylesheet" href="/css/modify.css">

    modify.styl 会被 Hexo 渲染成 modify.css 文件,所以此处应为 modify.css

  3. 增加插件脚本

    因为使用了 cheerio 来解析 HTML,所以需要先安装此依赖。

    1
    npm install cheerio

    新建一个文件,位于 scripts/modify.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
    "use strict";
    const cheerio = require("cheerio");

    /**
    * 在页面插入新顶部图
    * @param {cheerio.Root} $ Root
    */
    function insertTopImg($) {
    let header = $("#page-header");
    if (header.length === 0) return;
    let background = header.css("background-image");
    if (!background) return;
    $("#post, #page, #archive, #tag, #category").prepend(
    `<div class="top-img" style="background-image: ${background};"></div>`
    );
    }

    hexo.extend.filter.register("after_render:html", function (str, data) {
    let $ = cheerio.load(str, {
    decodeEntities: false,
    });
    insertTopImg($);
    return $.html();
    });

背景透明设置

查看步骤

参考大佬的教程,根据自己的喜好进行了更改,添加以下代码到custom.css文件(或者自己新建一个),然后在主题配置项引入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
62
63
64
65
66
67
68
69
/* 背景透明度 */
:root {
--trans-light: rgba(255, 255, 255, 0.8);
--trans-dark: rgba(25, 25, 25, 0.8);
}

/* 首页文章卡片 */
#recent-posts>.recent-post-item {
background: var(--trans-light);
}

/* 首页侧栏卡片 */
#aside-content .card-widget {
background: var(--trans-light);
}

/* 文章页、归档页、普通页面 */
div#post,
div#page,
div#archive {
background: var(--trans-light);
}

/* 导航栏 */
#page-header.nav-fixed #nav {
background: rgba(255, 255, 255, 0.88);
}

[data-theme="dark"] #page-header.nav-fixed #nav {
background: rgba(0, 0, 0, 0.7) !important;
}

/* 夜间模式遮罩 */
[data-theme="dark"] #recent-posts>.recent-post-item,
[data-theme="dark"] #aside-content .card-widget,
[data-theme="dark"] div#post,
[data-theme="dark"] div#archive,
[data-theme="dark"] div#page {
background: var(--trans-dark);
}

/* 夜间模式页脚页头遮罩透明 */
[data-theme="dark"] #footer::before {
background: transparent !important;
}

[data-theme="dark"] #page-header::before {
background: transparent !important;
}

/* 阅读模式 */
.read-mode #aside-content .card-widget {
background: rgba(249, 245, 233, 0.9) !important;
}

.read-mode div#post {
background: rgba(249, 245, 233, 0.9) !important;
}

/* 夜间模式下的阅读模式 */
[data-theme="dark"] .read-mode #aside-content .card-widget {
background: rgba(25, 25, 25, 0.9) !important;
color: #ffffff;
}

[data-theme="dark"] .read-mode div#post {
background: rgba(25, 25, 25, 0.9) !important;
color: #ffffff;
}

星空背景和流星特效

樱花飘落效果

小部件美化

站点动态 title

站点动态 title 是通过 js 监测是否聚焦于当前页面,从而替换标签显示内容。

查看步骤
  1. 在 [Blogroot]\themes\butterfly\source\js\ 目录下新建 title.js:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    //动态标题
    var OriginTitile = document.title;
    var titleTime;
    document.addEventListener('visibilitychange', function () {
    if (document.hidden) {
    //离开当前页面时标签显示内容
    document.title = 'w(゚Д゚)w 不要走!再看看嘛!';
    clearTimeout(titleTime);
    }
    else {
    //返回当前页面时标签显示内容
    document.title = '♪(^∇^*)欢迎回来!' + OriginTitile;
    //两秒后变回正常标题
    titleTime = setTimeout(function () {
    document.title = OriginTitile;
    }, 2000);
    }
    });
  2. 在 [Blogroot]_config.butterfly.yml 的 inject 配置项添加引入,此处因为这是个独立的 js,而且体量极小,所以可以添加 async 异步加载标签:

    1
    2
    3
    4
    5
    6
    inject:
    head:
    # - <link rel="stylesheet" href="/xxx.css">
    bottom:
    # - <script src="xxxx"></script>
    - <script async src="/js/title.js"></script>

修改标题样式 - 旋转小风车

查看步骤

参考教程:Hexo中Buttefly主题美化进阶续篇(十) | 偷掉月亮 (moonshuo.cn)

  1. 在主题配置文件中,更改相关配置如下,下面对应的为小风车的编号,可以更改为自己的编号

    1
    2
    3
    4
    5
    beautify:
    enable: true
    field: post # site/post
    title-prefix-icon: '\f863'
    title-prefix-icon-color: "#F47466"
  2. 在 Blog/themes/butterfly/source/css 文件下新建 custom.css 文件(按照自己喜好命名)

    在主题配置文件_config.butterfly.yml 中引入对应的 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
    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
    /* 文章页H1-H6图标样式效果 */
    /* 控制风车转动速度 4s那里可以自己调节快慢 */
    h1::before,
    h2::before,
    h3::before,
    h4::before,
    h5::before,
    h6::before {
    -webkit-animation: ccc 4s linear infinite;
    animation: ccc 4s linear infinite;
    }

    /* 控制风车转动方向 -1turn 为逆时针转动,1turn 为顺时针转动,相同数字部分记得统一修改 */
    @-webkit-keyframes ccc {
    0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
    }

    to {
    -webkit-transform: rotate(-1turn);
    transform: rotate(-1turn);
    }
    }

    @keyframes ccc {
    0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
    }

    to {
    -webkit-transform: rotate(-1turn);
    transform: rotate(-1turn);
    }
    }

    /* 设置风车颜色 */
    #content-inner.layout h1::before {
    color: #ef50a8;
    margin-left: -1.55rem;
    font-size: 1.3rem;
    margin-top: -0.23rem;
    }

    #content-inner.layout h2::before {
    color: #fb7061;
    margin-left: -1.35rem;
    font-size: 1.1rem;
    margin-top: -0.12rem;
    }

    #content-inner.layout h3::before {
    color: #ffbf00;
    margin-left: -1.22rem;
    font-size: 0.95rem;
    margin-top: -0.09rem;
    }

    #content-inner.layout h4::before {
    color: #a9e000;
    margin-left: -1.05rem;
    font-size: 0.8rem;
    margin-top: -0.09rem;
    }

    #content-inner.layout h5::before {
    color: #57c850;
    margin-left: -0.9rem;
    font-size: 0.7rem;
    margin-top: 0rem;
    }

    #content-inner.layout h6::before {
    color: #5ec1e0;
    margin-left: -0.9rem;
    font-size: 0.66rem;
    margin-top: 0rem;
    }

    /* s设置风车hover动效 6s那里可以自己调节快慢*/
    #content-inner.layout h1:hover,
    #content-inner.layout h2:hover,
    #content-inner.layout h3:hover,
    #content-inner.layout h4:hover,
    #content-inner.layout h5:hover,
    #content-inner.layout h6:hover {
    color: var(--theme-color);
    }

    #content-inner.layout h1:hover::before,
    #content-inner.layout h2:hover::before,
    #content-inner.layout h3:hover::before,
    #content-inner.layout h4:hover::before,
    #content-inner.layout h5:hover::before,
    #content-inner.layout h6:hover::before {
    color: var(--theme-color);
    -webkit-animation: ccc 6s linear infinite;
    animation: ccc 6s linear infinite;
    }

鼠标样式

查看步骤

参考教程:Hexo中Buttefly主题美化进阶(八) | 偷掉月亮 (moonshuo.cn)

可以直接引入超链接,也可以本地自定义图片,本教程采用本地方式

  1. 首先先找好图片或者cur文件

    图片的话不能太大,像素大小最好为50*50或者以下(可以自行更改图片像素大小),太大的话有时不会显示这个效果,而且那样的话网页的图标会显得很大,之后使用这个工具将图片转换为cur。 — > Convertio — 文件转换器

    我没有找图片,直接用的现成的cur,如果不知道用什么鼠标样式,可以打开下面的网站,里面有一些免费的,但是可能比较大,可以使用上面的工具先转换为图片,调整像素,然后在转换为回来。 — > 鼠标指针 - 光标 - 电脑鼠标指针下载 - 致美化 - 漫锋网 (zhutix.com)

  2. 引入

    \blog\themes\butterfly\source\css 文件夹下新建mouse,专门存储cru文件,将文件存储到下面。当然如果需要快捷切换到其他样式,也可以在mouse文件夹下面在新建。

    这里以custom.css为例,填写下面代码,当然也可以自己在css文件夹下面新建xxx.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
    /* 全局默认鼠标指针 */
    body,
    html {
    cursor: url('./mouse/ShaR/normal.cur'), auto !important;
    }

    /* 悬停图片时的鼠标指针 */
    img {

    cursor: url('./mouse/ShaR/move.cur'), auto !important;
    }

    /* 选择链接标签时的鼠标指针 */
    a:hover {
    cursor: url('./mouse/ShaR/link.cur'), auto;
    }

    /* 选中输入框时的鼠标指针 */
    input:hover {
    cursor: url('./mouse/ShaR/text.cur'), auto;
    }

    /* 悬停按钮时的鼠标指针 */
    button:hover {
    cursor: url('./mouse/ShaR/link.cur'), auto;
    }

    /* 悬停列表标签时的鼠标指针 */
    i:hover {
    cursor: url('./mouse/ShaR/link.cur'), auto;
    }

    /* 悬停页脚链接标签(例如页脚徽标)时的鼠标指针 */
    #footer-wrap a:hover {
    cursor: url('./mouse/ShaR/link.cur'), auto;
    }

    /* 悬停页码时的鼠标指针 */
    #pagination .page-number:hover {
    cursor: url('./mouse/ShaR/link.cur'), auto;
    }

    /* 悬停菜单栏时的鼠标指针 */
    #nav .site-page:hover {
    cursor: url('./mouse/ShaR/link.cur'), auto;
    }

顶部导航栏美化

页脚美化

查看步骤
  1. 添加各种小徽标

    找到_config.butterfly.yml文件的footer部分,更改custom_text

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    custom_text: |
    I wish you to become your own sun, no need to rely on who's light.
    <p>
    <a target="_blank" href="https://hexo.io/"><img src="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&logo=hexo" title="博客框架为Hexo"></a>&nbsp;
    <a target="_blank" href="https://butterfly.js.org/"><img src="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&logo=bitdefender" title="主题采用butterfly"></a>&nbsp;
    <a target="_blank" href="https://www.cloudflare.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-orange?style=flat&logo=Cloudflare" title="本站使用Cloudflare为静态资源提供CDN加速"></a>&nbsp;
    <a target="_blank" href="https://github.com/"><img src="https://img.shields.io/badge/Source-Github-d021d6?style=flat&logo=GitHub" title="本站项目由Gtihub托管"></a>&nbsp;
    <a target="_blank" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img src="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&logo=Claris" title="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可"></a>
    </p>
    当前CDN节点: <span id="cdn"></span>
  2. 页脚显示当前Cloudflare CDN节点

    原理:Cloudflare为所有客户加上了/cdn-cgi/端点,任何一个套了Cloudflare的网站访问 example.com/cdn-cgi/trace 后都会返回用户现在的信息,如ip地址、CDN节点、是否开启WARP、tls协议版本等。那么就可以在前端访问这个端点,再进行解析,将内容写入前段对应id的标签内,就可以呈现出目前的用户与Cloudflare CDN间的关系了。

    由于使用了jQuery来访问cdn-cgi,所以使用这个脚本需要先引入这个库。已经引入了此库的博客无需再次引入。

    _config.butterfly.yml文件的inject部分,修改bottom,添加

    - <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>

    \blog\themes\butterfly\source\js 目录创建cfcdn.js,填入以下内容

    1
    $(document).ready($.ajax({url: "/cdn-cgi/trace",success: function(data, status) {let areas=['{"s":"TNR","l":"Antananarivo, Madagascar"}','{"s":"CPT","l":"Cape Town, South Africa"}','{"s":"CMN","l":"Casablanca, Morocco"}','{"s":"DAR","l":"Dar Es Salaam, Tanzania"}','{"s":"JIB","l":"Djibouti City, Djibouti"}','{"s":"DUR","l":"Durban, South Africa"}','{"s":"JNB","l":"Johannesburg, South Africa"}','{"s":"KGL","l":"Kigali, Rwanda"}','{"s":"LOS","l":"Lagos, Nigeria"}','{"s":"LAD","l":"Luanda, Angola"}','{"s":"MPM","l":"Maputo, MZ"}','{"s":"MBA","l":"Mombasa, Kenya"}','{"s":"MRU","l":"Port Louis, Mauritius"}','{"s":"RUN","l":"Réunion, France"}','{"s":"BLR","l":"Bangalore, India"}','{"s":"BKK","l":"Bangkok, Thailand"}','{"s":"BWN","l":"Bandar Seri Begawan, Brunei"}','{"s":"CEB","l":"Cebu, Philippines"}','{"s":"CTU","l":"成都, 🇨🇳 中国大陆"}','{"s":"MAA","l":"Chennai, India"}','{"s":"CGP","l":"Chittagong, Bangladesh"}','{"s":"CKG","l":"重庆, 🇨🇳 中国大陆"}','{"s":"CMB","l":"Colombo, Sri Lanka"}','{"s":"DAC","l":"Dhaka, Bangladesh"}','{"s":"SZX","l":"东莞, 🇨🇳 中国大陆"}','{"s":"FUO","l":"佛山, 🇨🇳 中国大陆"}','{"s":"FOC","l":"福州, 🇨🇳 中国大陆"}','{"s":"CAN","l":"广州, 🇨🇳 中国大陆"}','{"s":"HGH","l":"杭州, 🇨🇳 中国大陆"}','{"s":"HAN","l":"Hanoi, Vietnam"}','{"s":"HNY","l":"衡阳, 🇨🇳 中国大陆"}','{"s":"SGN","l":"Ho Chi Minh City, Vietnam"}','{"s":"HKG","l":"🇭🇰 香港"}','{"s":"HYD","l":"Hyderabad, India"}','{"s":"ISB","l":"Islamabad, Pakistan"}','{"s":"CGK","l":"Jakarta, Indonesia"}','{"s":"TNA","l":"济南, 🇨🇳 中国大陆"}','{"s":"KHI","l":"Karachi, Pakistan"}','{"s":"KTM","l":"Kathmandu, Nepal"}','{"s":"CCU","l":"Kolkata, India"}','{"s":"KUL","l":"Kuala Lumpur, Malaysia"}','{"s":"LHE","l":"Lahore, Pakistan"}','{"s":"NAY","l":"廊坊, 🇨🇳 中国大陆"}','{"s":"LYA","l":"洛阳, 🇨🇳 中国大陆"}','{"s":"MFM","l":"🇲🇴 澳门"}','{"s":"MLE","l":"Malé, Maldives"}','{"s":"MNL","l":"Manila, Philippines"}','{"s":"BOM","l":"Mumbai, India"}','{"s":"NAG","l":"Nagpur, India"}','{"s":"NNG","l":"南宁, 🇨🇳 中国大陆"}','{"s":"DEL","l":"New Delhi, India"}','{"s":"KIX","l":"Osaka, Japan"}','{"s":"PNH","l":"Phnom Penh, Cambodia"}','{"s":"TAO","l":"青岛, 🇨🇳 中国大陆"}','{"s":"ICN","l":"Seoul, South Korea"}','{"s":"SHA","l":"上海, 🇨🇳 中国大陆"}','{"s":"SHE","l":"沈阳, 🇨🇳 中国大陆"}','{"s":"SJW","l":"石家庄, 🇨🇳 中国大陆"}','{"s":"SIN","l":"Singapore, Singapore"}','{"s":"SZV","l":"苏州, 🇨🇳 中国大陆"}','{"s":"TPE","l":"台北, 🇨🇳 台湾"}','{"s":"PBH","l":"Thimphu, Bhutan"}','{"s":"TSN","l":"天津, 🇨🇳 中国大陆"}','{"s":"NRT","l":"Tokyo, Japan"}','{"s":"ULN","l":"Ulaanbaatar, Mongolia"}','{"s":"VTE","l":"Vientiane, Laos"}','{"s":"WUH","l":"武汉, 🇨🇳 中国大陆"}','{"s":"WUX","l":"无锡, 🇨🇳 中国大陆"}','{"s":"XIY","l":"西安, 🇨🇳 中国大陆"}','{"s":"EVN","l":"Yerevan, Armenia"}','{"s":"CGO","l":"郑州, 🇨🇳 中国大陆"}','{"s":"CSX","l":"株洲, 🇨🇳 中国大陆"}','{"s":"AMS","l":"Amsterdam, Netherlands"}','{"s":"ATH","l":"Athens, Greece"}','{"s":"BCN","l":"Barcelona, Spain"}','{"s":"BEG","l":"Belgrade, Serbia"}','{"s":"TXL","l":"Berlin, Germany"}','{"s":"BRU","l":"Brussels, Belgium"}','{"s":"OTP","l":"Bucharest, Romania"}','{"s":"BUD","l":"Budapest, Hungary"}','{"s":"KIV","l":"Chișinău, Moldova"}','{"s":"CPH","l":"Copenhagen, Denmark"}','{"s":"ORK","l":"Cork, Ireland"}','{"s":"DUB","l":"Dublin, Ireland"}','{"s":"DUS","l":"Düsseldorf, Germany"}','{"s":"EDI","l":"Edinburgh, United Kingdom"}','{"s":"FRA","l":"Frankfurt, Germany"}','{"s":"GVA","l":"Geneva, Switzerland"}','{"s":"GOT","l":"Gothenburg, Sweden"}','{"s":"HAM","l":"Hamburg, Germany"}','{"s":"HEL","l":"Helsinki, Finland"}','{"s":"IST","l":"Istanbul, Turkey"}','{"s":"KBP","l":"Kyiv, Ukraine"}','{"s":"LIS","l":"Lisbon, Portugal"}','{"s":"LHR","l":"London, United Kingdom"}','{"s":"LUX","l":"Luxembourg City, Luxembourg"}','{"s":"MAD","l":"Madrid, Spain"}','{"s":"MAN","l":"Manchester, United Kingdom"}','{"s":"MRS","l":"Marseille, France"}','{"s":"MXP","l":"Milan, Italy"}','{"s":"DME","l":"Moscow, Russia"}','{"s":"MUC","l":"Munich, Germany"}','{"s":"LCA","l":"Nicosia, Cyprus"}','{"s":"OSL","l":"Oslo, Norway"}','{"s":"CDG","l":"Paris, France"}','{"s":"PRG","l":"Prague, Czech Republic"}','{"s":"KEF","l":"Reykjavík, Iceland"}','{"s":"RIX","l":"Riga, Latvia"}','{"s":"FCO","l":"Rome, Italy"}','{"s":"LED","l":"Saint Petersburg, Russia"}','{"s":"SOF","l":"Sofia, Bulgaria"}','{"s":"ARN","l":"Stockholm, Sweden"}','{"s":"TLL","l":"Tallinn, Estonia"}','{"s":"SKG","l":"Thessaloniki, Greece"}','{"s":"VIE","l":"Vienna, Austria"}','{"s":"VNO","l":"Vilnius, Lithuania"}','{"s":"WAW","l":"Warsaw, Poland"}','{"s":"ZAG","l":"Zagreb, Croatia"}','{"s":"ZRH","l":"Zürich, Switzerland"}','{"s":"ARI","l":"Arica, Chile"}','{"s":"ASU","l":"Asunción, Paraguay"}','{"s":"BOG","l":"Bogotá, Colombia"}','{"s":"EZE","l":"Buenos Aires, Argentina"}','{"s":"CWB","l":"Curitiba, Brazil"}','{"s":"FOR","l":"Fortaleza, Brazil"}','{"s":"GUA","l":"Guatemala City, Guatemala"}','{"s":"LIM","l":"Lima, Peru"}','{"s":"MDE","l":"Medellín, Colombia"}','{"s":"PTY","l":"Panama City, Panama"}','{"s":"POA","l":"Porto Alegre, Brazil"}','{"s":"UIO","l":"Quito, Ecuador"}','{"s":"GIG","l":"Rio de Janeiro, Brazil"}','{"s":"GRU","l":"São Paulo, Brazil"}','{"s":"SCL","l":"Santiago, Chile"}','{"s":"CUR","l":"Willemstad, Curaçao"}','{"s":"GND","l":"St. George‘s, Grenada"}','{"s":"AMM","l":"Amman, Jordan"}','{"s":"BGW","l":"Baghdad, Iraq"}','{"s":"GYD","l":"Baku, Azerbaijan"}','{"s":"BEY","l":"Beirut, Lebanon"}','{"s":"DOH","l":"Doha, Qatar"}','{"s":"DXB","l":"Dubai, United Arab Emirates"}','{"s":"KWI","l":"Kuwait City, Kuwait"}','{"s":"BAH","l":"Manama, Bahrain"}','{"s":"MCT","l":"Muscat, Oman"}','{"s":"ZDM","l":"Ramallah"}','{"s":"RUH","l":"Riyadh, Saudi Arabia"}','{"s":"TLV","l":"Tel Aviv, Israel"}','{"s":"IAD","l":"Ashburn, VA, United States"}','{"s":"ATL","l":"Atlanta, GA, United States"}','{"s":"BOS","l":"Boston, MA, United States"}','{"s":"BUF","l":"Buffalo, NY, United States"}','{"s":"YYC","l":"Calgary, AB, Canada"}','{"s":"CLT","l":"Charlotte, NC, United States"}','{"s":"ORD","l":"Chicago, IL, United States"}','{"s":"CMH","l":"Columbus, OH, United States"}','{"s":"DFW","l":"Dallas, TX, United States"}','{"s":"DEN","l":"Denver, CO, United States"}','{"s":"DTW","l":"Detroit, MI, United States"}','{"s":"HNL","l":"Honolulu, HI, United States"}','{"s":"IAH","l":"Houston, TX, United States"}','{"s":"IND","l":"Indianapolis, IN, United States"}','{"s":"JAX","l":"Jacksonville, FL, United States"}','{"s":"MCI","l":"Kansas City, MO, United States"}','{"s":"LAS","l":"Las Vegas, NV, United States"}','{"s":"LAX","l":"Los Angeles, CA, United States"}','{"s":"MFE","l":"McAllen, TX, United States"}','{"s":"MEM","l":"Memphis, TN, United States"}','{"s":"MEX","l":"Mexico City, Mexico"}','{"s":"MIA","l":"Miami, FL, United States"}','{"s":"MSP","l":"Minneapolis, MN, United States"}','{"s":"MGM","l":"Montgomery, AL, United States"}','{"s":"YUL","l":"Montréal, QC, Canada"}','{"s":"BNA","l":"Nashville, TN, United States"}','{"s":"EWR","l":"Newark, NJ, United States"}','{"s":"ORF","l":"Norfolk, VA, United States"}','{"s":"OMA","l":"Omaha, NE, United States"}','{"s":"PHL","l":"Philadelphia, United States"}','{"s":"PHX","l":"Phoenix, AZ, United States"}','{"s":"PIT","l":"Pittsburgh, PA, United States"}','{"s":"PAP","l":"Port-Au-Prince, Haiti"}','{"s":"PDX","l":"Portland, OR, United States"}','{"s":"QRO","l":"Queretaro, MX, Mexico"}','{"s":"RIC","l":"Richmond, Virginia"}','{"s":"SMF","l":"Sacramento, CA, United States"}','{"s":"SLC","l":"Salt Lake City, UT, United States"}','{"s":"SAN","l":"San Diego, CA, United States"}','{"s":"SJC","l":"San Jose, CA, United States"}','{"s":"YXE","l":"Saskatoon, SK, Canada"}','{"s":"SEA","l":"Seattle, WA, United States"}','{"s":"STL","l":"St. Louis, MO, United States"}','{"s":"TPA","l":"Tampa, FL, United States"}','{"s":"YYZ","l":"Toronto, ON, Canada"}','{"s":"YVR","l":"Vancouver, BC, Canada"}','{"s":"TLH","l":"Tallahassee, FL, United States"}','{"s":"YWG","l":"Winnipeg, MB, Canada"}','{"s":"ADL","l":"Adelaide, SA, Australia"}','{"s":"AKL","l":"Auckland, New Zealand"}','{"s":"BNE","l":"Brisbane, QLD, Australia"}','{"s":"MEL","l":"Melbourne, VIC, Australia"}','{"s":"NOU","l":"Noumea, New caledonia"}','{"s":"PER","l":"Perth, WA, Australia"}','{"s":"SYD","l":"Sydney, NSW, Australia"}'];let area = data.split("colo=")[1].split("\n")[0];for (var i = 0; i < areas.length; i++) {const as = JSON.parse(areas[i]);if (as.s == area) {document.getElementById("cdn").innerHTML = as.l;break;}}}}));

    在想要呈现节点信息的地方添加<span id="cdn"></span>即可,比如上方第一步添加各种小徽标

  3. 参考

彩色动态图标

查看步骤

新建图标项目

  1. 访问阿里巴巴矢量图标库 , 注册登录。
  2. 搜索自己心仪的图标,然后选择添加入库,加到购物车。
  3. 选择完毕后点击右上角的购物车图标,打开侧栏,选择添加到项目,如果没有项目就新建一个。
  4. 可以通过上方顶栏菜单 -> 资源管理 -> 我的项目,找到之前添加的图标项目。(现在的 iconfont 可以在图标库的项目设置里直接打开彩色设置,然后采用 fontclass 的引用方式即可使用多彩图标。但是单一项目彩色图标上限是 40 个图标,酌情采用。)

引入图标

简介:

  • 线上引入方案,使用官方文档中最便捷的font-class方案。这一方案偶尔会出现图标加载不出的情况。但是便于随时对图标库进行升级,换一下在线链接即可,适合新手使用。最新版本的iconfont支持直接在项目设置中开启彩色图标,从而实现直接用class添加多彩色图标。

  • 本地引入方案是基于官方文档的Unicodefont-class方案原理。
    相比于线上引入方案偶尔会出现图标加载不出的情况。本地引入方案则可以说万无一失。但是图标库更新则需要更换包括字体文件在内的诸多内容。

  • 外挂标签写法基于官方方案的symbol引入方案,所以在浏览器支持上有其局限性。但是不得不承认,这一方案是效果最好的。且引入方式也较为简单。
    为了书写方便,我将官方较为繁琐的写法封装成了外挂标签[Tag],具体写法详见示例。

  • fontclass的彩色图标,为了避免css文件过大,官方设置了限制,单一项目内彩色图标个数上限是40个。总结下来,fontclass是最适合萌新的方案。而symbol引入方案依然是最优解。

  1. 打开[Blogroot]\themes\butterfly\source\css\custom.css,输入以下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* 图标 */
    svg.icon {
    width: 1.15em;
    height: 1.15em;
    /* width和height定义图标的默认宽度和高度*/
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
    }
  2. 找到之前新建的图标项目,选择Symbol->查看在线链接,获取Symbol.js的在线链接,并引入。

    Butterfly主题为例,在[Blogroot]\_config.butterfly.ymlinject配置项中填入:

    1
    2
    3
    4
    5
    6
    inject:
    head:
    - <link rel="stylesheet" href="/css/custom.css">
    - <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/font-awesome-animation.min.css"> # 引入font-awesome动画依赖,参考https://github.com/l-lin/font-awesome-animation
    bottom:
    - <script async src="//at.alicdn.com/t/font_xxx.js"></script>

    //at.alicdn.com/t/font_xxx.js替换为自己的链接,此处async是异步加载属性,能够减少HTML阻塞。

  3. 添加外挂标签,在[Blogroot]\themes\butterfly\scripts\tag\目录下新建iconfont.js,打开[Blogroot]\themes\butterfly\scripts\tag\iconfont.js,输入:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    'use strict';

    function iconFont(args) {
    args = args.join(' ').split(',')
    let p0 = args[0]
    let p1 = args[1]?args[1]:1
    return `<svg class="icon" style="width:${p1}em; height:${p1}em" aria-hidden="true"><use xlink:href="#${p0}"></use></svg>`;
    }

    hexo.extend.tag.register('icon',iconFont);

    添加外挂标签后可以使用外挂标签的形式来写入图标

    1
    {% icon [icon-xxxx],[font-size] %}
    • icon-xxxx:表示图标font-class,可以在自己的阿里矢量图标库项目的font-class引用方案内查询并复制。

    • font-size:表示图标大小,直接填写数字即可,单位为em。图标大小默认值为1em

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    {% icon icon-rat_zi %}{% icon icon-rat,2 %}

    {% icon icon-ox_chou,3 %}{% icon icon-ox,4 %}

    {% icon icon-tiger_yin,5 %}{% icon icon-tiger,6 %}

    {% icon icon-rabbit_mao,1 %}{% icon icon-rabbit,2 %}

    {% icon icon-dragon_chen,3 %}{% icon icon-dragon,4 %}

    {% icon icon-snake_si,5 %}{% icon icon-snake,6 %}

    {% icon icon-horse_wu %}{% icon icon-horse,2 %}

    {% icon icon-goat_wei,3 %}{% icon icon-goat,4 %}

    {% icon icon-monkey_shen,5 %}{% icon icon-monkey,6 %}

    {% icon icon-rooster_you %}{% icon icon-rooster,2 %}

    {% icon icon-dog_xu,3 %}{% icon icon-dog,4 %}

    {% icon icon-boar_hai,5 %}{% icon icon-boar,6 %}

添加动态效果

  1. 菜单栏

    我这里 butterfly 版本为4.12.0,如果版本相差太大,就不要直接替换了,注意自己做好备份。

    [BlogRoot]\themes\butterfly\layout\includes\header\menu_item.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
    38
    39
    40
    41
    42
    43
    44
    if theme.menu
    //- for mobile sidebar
    - let sidebarChildHide = theme.hide_sidebar_menu_child ? 'hide' : ''

    .menus_items
    each value, label in theme.menu
    if typeof value !== 'object'
    .menus_item
    a.site-page.faa-parent.animated-hover(href=url_for(trim(value.split('||')[0])))
    if value.split('||')[1]
    - var icon_value = trim(value.split('||')[1])
    - var anima_value = value.split('||')[2] ? trim(value.split('||')[2]) : 'faa-tada'
    if icon_value.substring(0,2)=="fa"
    i.fa-fw(class=icon_value + ' ' + anima_value)
    else if icon_value.substring(0,4)=="icon"
    svg.icon(aria-hidden="true" class=anima_value)
    use(xlink:href=`#`+ icon_value)
    span=' '+label
    else
    .menus_item
    a.site-page.faa-parent.animated-hover(href='javascript:void(0);')
    if label.split('||')[1]
    - var icon_label = trim(label.split('||')[1])
    - var anima_label = label.split('||')[2] ? trim(label.split('||')[2]) : 'faa-tada'
    if icon_label.substring(0,2)=="fa"
    i.fa-fw(class=icon_label + ' ' + anima_label)
    else if icon_label.substring(0,4)=="icon"
    svg.icon(aria-hidden="true" class=anima_label)
    use(xlink:href=`#`+ icon_label)
    span=' '+ trim(label.split('||')[0])
    i.fas.fa-chevron-down.expand(class=sidebarChildHide)
    ul.menus_item_child
    each val,lab in value
    li
    a.site-page.child.faa-parent.animated-hover(href=url_for(trim(val.split('||')[0])))
    if val.split('||')[1]
    - var icon_val = trim(val.split('||')[1])
    - var anima_val = val.split('||')[2] ? trim(val.split('||')[2]) : 'faa-tada'
    if icon_val.substring(0,2)=="fa"
    i.fa-fw(class=icon_val + ' ' + anima_val)
    else if icon_val.substring(0,4)=="icon"
    svg.icon(aria-hidden="true" class=anima_val)
    use(xlink:href=`#`+ icon_val)
    span=' '+ lab

    然后修改[Blogroot]\_config.butterfly.yml 配置,把原来的 fas fa-xxxx 就可以修改为你的 icon 图标名,后面在跟上动态效果名,例如faa-tada,更多自行查找:GitHub - l-lin/font-awesome-animation:使用 FontAwesome 和一些 CSS3 的简单动画。

    比如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    menu:
    首页: / || icon-home || faa-tada
    文章||icon-article || faa-tada || hide:
    分类: /categories/ || icon-Classification || faa-tada
    标签: /tags/ || icon-tag || faa-tada
    时间轴: /archives/ || icon-archive2 || faa-tada
    友链: /link/ || icon-link || faa-tada
    留言板: /comment/ || icon-message || faa-tada
    关于: /about/ || icon-about || faa-tada

    其中 hide 是默认不展开折叠。

    我这里备份一下我的menu_item.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
    if theme.menu
    .menus_items
    each value, label in theme.menu
    if typeof value !== 'object'
    .menus_item
    - const valueArray = value.split('||')
    a.site-page(href=url_for(trim(valueArray[0])))
    if valueArray[1]
    i.fa-fw(class=trim(valueArray[1]))
    span=' '+label
    else
    .menus_item
    - const labelArray = label.split('||')
    - const hideClass = labelArray[2] && trim(labelArray[2]) === 'hide' ? 'hide' : ''
    a.site-page.group(class=`${hideClass}` href='javascript:void(0);')
    if labelArray[1]
    i.fa-fw(class=trim(labelArray[1]))
    span=' '+ trim(labelArray[0])
    i.fas.fa-chevron-down
    ul.menus_item_child
    each val,lab in value
    - const valArray = val.split('||')
    li
    a.site-page.child(href=url_for(trim(valArray[0])))
    if valArray[1]
    i.fa-fw(class=trim(valArray[1]))
    span=' '+ lab

social 社交卡片彩色动态图标

注:需要先完成菜单栏彩色动态图标 这一步

  1. [Blogroot]\themes\butterfly\layout\includes\header\social.pug 替换为以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    each value, title in theme.social
    a.social-icon.faa-parent.animated-hover(href=url_for(trim(value.split('||')[0])) target="_blank" title=title === undefined ? '' : trim(title))
    if value.split('||')[1]
    - var icon_value = trim(value.split('||')[1])
    - var anima_value = value.split('||')[2] ? trim(value.split('||')[2]) : 'faa-tada'
    if icon_value.substring(0,2)=="fa"
    i.fa-fw(class=icon_value + ' ' + anima_value)
    else if icon_value.substring(0,4)=="icon"
    svg.icon(aria-hidden="true" class=anima_value)
    use(xlink:href=`#`+ icon_value)
  2. 修改 [Blogroot]\_config.butterfly.yml 的 social 配置项。

    1
    2
    3
    4
    5
    social:
    # iconfont彩色图标
    Github: https://github.com/xxxxx || icon-GitHub || faa-bounce
    # fontawesome单色图标
    Email: mailto:[email protected] || icon-mail || faa-bounce

    注:写法和原来不一样了
    原来:图标:跳转链接 || 注释
    现在:注释:跳转链接 || 图标名 || 动态效果名

    我这里备份一下我的menu_item.pug 原本的内容:

    1
    待。。。

    参考

    特别感谢以下大佬:

添加卡通人物(加强版看板娘)

查看步骤
  1. 下载

    如果已经安装过官方提供的live2d,需要先卸载!

    npm uninstall hexo-helper-live2d

    然后下载经过张书樵大神魔改后的项目:GitHub - stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platform

    下载解压到:themes\butterfly\source\文件夹下

  2. 设置绝对路径

    打开项目目录进入修改autoload.js文件,将live2d_path设为自己的路径,一般没什么太大变化都为

    /live2d-widget/

  3. 引入

    打开butterfly下的layout下的includes目录,点击修改head.pug文件,在文件末尾粘贴:

    script(src='/live2d-widget/autoload.js')

    最后在主题配置文件下即butterfly下的_config.yml(如果配置了 _config.butterfly.yml,则使用这个配置文件)中开启看板娘:

    1
    2
    3
    # 看板娘
    live2d:
    enable: true
  4. 自定义配置(随意)

  • 修改看板娘的位置
    在live2d-widget目录下的waifu.css中可以修改画布位置使得看板娘显示在你指定的位置,具体在#waifu选择器下修改
  • 修改聊天内容
    可以在live2d-widget文件夹下的waifu-tips.json文件中修改,进去就可以看到大量的文本内容
  • 修改首次加载的模型
    如果你不喜欢默认的第一个模型,可以指定首次加载的模型,具体配置在live2d-widget文件夹下的src/index.js中的大约133行,原作者也在这里注释了模型的ID,默认为1,后面的模型依次递增(待补充)

版权美化(渐变色)

添加功能

文章加密

查看步骤
  1. 安装插件

    1
    npm install --save hexo-blog-encrypt
  2. 启用

    /blog/_config.yml文件中添加以下内容:

    1
    2
    3
    #文字加密
    encrypt:
    enable: true
  3. 使用(仅单篇文章加密)

    在想要使用加密功能的文字头部加上对应文字:

    1
    2
    3
    4
    password: 123456 
    abstract: 欢迎来到我的博客,输入密码阅读
    message: Hey, 这篇文章被加密了,请输入密码!
    wrong_pass_message: Oh, 密码错了,检查一下好吗~
    • password: 该篇文章使用的密码
    • abstract: 摘要文字(少量)
    • message: 密码框上的描述性文字

添加评论

查看步骤

本教程采用waline评论系统

  1. 介绍

  2. 配置waline

    直接查看官方教程:快速上手 | Waline

    简单来说就是:注册LeanCloud并创建应用,Vercel 部署 (服务端),主题配置文件启用

  3. 在Butterfly主题中启用waline

    Butterfly 安裝文檔(四) 主題配置-2 | Butterfly

    更改commentswaline部分

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    comments:
    # 最多两个注释系统,第一个将显示为默认值
    # 选择:Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/Artalk
    use: Waline # Valine,Disqus
    text: true # 在按钮旁边显示注释名称
    # lazyload: 注释系统将在注释元素进入浏览器视口时加载。
    # 如果将其设置为true,则注释计数将无效
    lazyload: false
    count: true # 在文章的top_img中显示评论计数
    card_post_count: false # 在主页中显示评论计数

    waline:
    serverURL: # Waline服务器地址url,比如https://example.yourdomain.com,后面不要加`/`
    bg: # waline 背景
    pageview: false
    option:
    locale:
    placeholder: 小站已开启评论审核,可匿名评论,但评论需要通过审核后才能够出现在评论区哦~
    emoji: [
    'https://unpkg.com/@waline/[email protected]/alus',
    'https://unpkg.com/@waline/[email protected]/weibo',
    ]
    pageSize: 10 # 评论每页显示数量
    highlight: true

    emoji自行寻找,官方提供的有一些:表情选项卡 | Waline

    网上发现的表情库:

添加欢迎弹窗

查看步骤
  1. 新建文件

    在博客根目录往下找到\themes\butterfly\source\js文件夹,新建sweetalert.js,文件内容:

    1
    !function(w,C,S){"use strict";!function o(a,r,s){function l(n,e){if(!r[n]){if(!a[n]){var t="function"==typeof require&&require;if(!e&&t)return t(n,!0);if(i)return i(n,!0);e=new Error("Cannot find module '"+n+"'");throw e.code="MODULE_NOT_FOUND",e}t=r[n]={exports:{}};a[n][0].call(t.exports,function(e){var t=a[n][1][e];return l(t||e)},t,t.exports,o,a,r,s)}return r[n].exports}for(var i="function"==typeof require&&require,e=0;e<s.length;e++)l(s[e]);return l}({1:[function(e,t,n){function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(n,"__esModule",{value:!0});var c,d,a,f,p=e("./modules/handle-dom"),m=e("./modules/utils"),y=e("./modules/handle-swal-dom"),v=e("./modules/handle-click"),h=o(e("./modules/handle-key")),b=o(e("./modules/default-params")),g=o(e("./modules/set-params"));n.default=a=f=function(){var t=arguments[0];function e(e){return(t[e]===S?b.default:t)[e]}if(p.addClass(C.body,"stop-scrolling"),y.resetInput(),t===S)return m.logStr("SweetAlert expects at least 1 attribute!"),!1;var n=m.extend({},b.default);switch(typeof t){case"string":n.title=t,n.text=arguments[1]||"",n.type=arguments[2]||"";break;case"object":if(t.title===S)return m.logStr('Missing "title" argument!'),!1;for(var o in n.title=t.title,b.default)n[o]=e(o);n.confirmButtonText=n.showCancelButton?"Confirm":b.default.confirmButtonText,n.confirmButtonText=e("confirmButtonText"),n.doneFunction=arguments[1]||null;break;default:return m.logStr('Unexpected type of argument! Expected "string" or "object", got '+typeof t),!1}g.default(n),y.fixVerticalPosition(),y.openModal(arguments[1]);for(var a=y.getModal(),r=a.querySelectorAll("button"),s=["onclick","onmouseover","onmouseout","onmousedown","onmouseup","onfocus"],l=function(e){return v.handleButton(e,n,a)},i=0;i<r.length;i++)for(var u=0;u<s.length;u++)r[i][s[u]]=l;y.getOverlay().onclick=l,c=w.onkeydown;w.onkeydown=function(e){return h.default(e,n,a)},w.onfocus=function(){setTimeout(function(){d!==S&&(d.focus(),d=S)},0)},f.enableButtons()},a.setDefaults=f.setDefaults=function(e){if(!e)throw new Error("userParams is required");if("object"!=typeof e)throw new Error("userParams has to be a object");m.extend(b.default,e)},a.close=f.close=function(){var t=y.getModal(),e=(p.fadeOut(y.getOverlay(),5),p.fadeOut(t,5),p.removeClass(t,"showSweetAlert"),p.addClass(t,"hideSweetAlert"),p.removeClass(t,"visible"),t.querySelector(".sa-icon.sa-success")),e=(p.removeClass(e,"animate"),p.removeClass(e.querySelector(".sa-tip"),"animateSuccessTip"),p.removeClass(e.querySelector(".sa-long"),"animateSuccessLong"),t.querySelector(".sa-icon.sa-error")),e=(p.removeClass(e,"animateErrorIcon"),p.removeClass(e.querySelector(".sa-x-mark"),"animateXMark"),t.querySelector(".sa-icon.sa-warning"));return p.removeClass(e,"pulseWarning"),p.removeClass(e.querySelector(".sa-body"),"pulseWarningIns"),p.removeClass(e.querySelector(".sa-dot"),"pulseWarningIns"),setTimeout(function(){var e=t.getAttribute("data-custom-class");p.removeClass(t,e)},300),p.removeClass(C.body,"stop-scrolling"),w.onkeydown=c,w.previousActiveElement&&w.previousActiveElement.focus(),d=S,clearTimeout(t.timeout),!0},a.showInputError=f.showInputError=function(e){var t=y.getModal(),n=t.querySelector(".sa-input-error"),n=(p.addClass(n,"show"),t.querySelector(".sa-error-container"));p.addClass(n,"show"),n.querySelector("p").innerHTML=e,setTimeout(function(){a.enableButtons()},1),t.querySelector("input").focus()},a.resetInputError=f.resetInputError=function(e){if(e&&13===e.keyCode)return!1;var e=y.getModal(),t=e.querySelector(".sa-input-error"),t=(p.removeClass(t,"show"),e.querySelector(".sa-error-container"));p.removeClass(t,"show")},a.disableButtons=f.disableButtons=function(e){var t=y.getModal(),n=t.querySelector("button.confirm"),t=t.querySelector("button.cancel");n.disabled=!0,t.disabled=!0},a.enableButtons=f.enableButtons=function(e){var t=y.getModal(),n=t.querySelector("button.confirm"),t=t.querySelector("button.cancel");n.disabled=!1,t.disabled=!1},void 0!==w?w.sweetAlert=w.swal=a:m.logStr("SweetAlert is a frontend module!"),t.exports=n.default},{"./modules/default-params":2,"./modules/handle-click":3,"./modules/handle-dom":4,"./modules/handle-key":5,"./modules/handle-swal-dom":6,"./modules/set-params":8,"./modules/utils":9}],2:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});n.default={title:"",text:"",type:null,allowOutsideClick:!1,showConfirmButton:!0,showCancelButton:!1,closeOnConfirm:!0,closeOnCancel:!0,confirmButtonText:"OK",confirmButtonColor:"#8CD4F5",cancelButtonText:"Cancel",imageUrl:null,imageSize:null,timer:null,customClass:"",html:!1,animation:!0,allowEscapeKey:!0,inputType:"text",inputPlaceholder:"",inputValue:"",showLoaderOnConfirm:!1},t.exports=n.default},{}],3:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});function m(e,t){var n=!0;h.hasClass(e,"show-input")&&(n=(n=e.querySelector("input").value)||""),t.doneFunction(n),t.closeOnConfirm&&sweetAlert.close(),t.showLoaderOnConfirm&&sweetAlert.disableButtons()}function y(e,t){var n=String(t.doneFunction).replace(/\s/g,"");"function("===n.substring(0,9)&&")"!==n.substring(9,10)&&t.doneFunction(!1),t.closeOnCancel&&sweetAlert.close()}var v=e("./utils"),h=(e("./handle-swal-dom"),e("./handle-dom"));n.default={handleButton:function(e,t,n){var o,a,r,e=e||w.event,s=e.target||e.srcElement,l=-1!==s.className.indexOf("confirm"),i=-1!==s.className.indexOf("sweet-overlay"),u=h.hasClass(n,"visible"),c=t.doneFunction&&"true"===n.getAttribute("data-has-done-function");function d(e){l&&t.confirmButtonColor&&(s.style.backgroundColor=e)}switch(l&&t.confirmButtonColor&&(o=t.confirmButtonColor,a=v.colorLuminance(o,-.04),r=v.colorLuminance(o,-.14)),e.type){case"mouseover":d(a);break;case"mouseout":d(o);break;case"mousedown":d(r);break;case"mouseup":d(a);break;case"focus":var f=n.querySelector("button.confirm"),p=n.querySelector("button.cancel");l?p.style.boxShadow="none":f.style.boxShadow="none";break;case"click":p=n===s,f=h.isDescendant(n,s);if(!p&&!f&&u&&!t.allowOutsideClick)break;l&&c&&u?m(n,t):c&&u||i?y(0,t):h.isDescendant(n,s)&&"BUTTON"===s.tagName&&sweetAlert.close()}},handleConfirm:m,handleCancel:y},t.exports=n.default},{"./handle-dom":4,"./handle-swal-dom":6,"./utils":9}],4:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});function o(e,t){return new RegExp(" "+t+" ").test(" "+e.className+" ")}function a(e){e.style.opacity="",e.style.display="block"}function r(e){e.style.opacity="",e.style.display="none"}n.hasClass=o,n.addClass=function(e,t){o(e,t)||(e.className+=" "+t)},n.removeClass=function(e,t){var n=" "+e.className.replace(/[\t\r\n]/g," ")+" ";if(o(e,t)){for(;0<=n.indexOf(" "+t+" ");)n=n.replace(" "+t+" "," ");e.className=n.replace(/^\s+|\s+$/g,"")}},n.escapeHtml=function(e){var t=C.createElement("div");return t.appendChild(C.createTextNode(e)),t.innerHTML},n._show=a,n.show=function(e){if(e&&!e.length)return a(e);for(var t=0;t<e.length;++t)a(e[t])},n._hide=r,n.hide=function(e){if(e&&!e.length)return r(e);for(var t=0;t<e.length;++t)r(e[t])},n.isDescendant=function(e,t){for(var n=t.parentNode;null!==n;){if(n===e)return!0;n=n.parentNode}return!1},n.getTopMargin=function(e){e.style.left="-9999px",e.style.display="block";var t=e.clientHeight,n="undefined"!=typeof getComputedStyle?parseInt(getComputedStyle(e).getPropertyValue("padding-top"),10):parseInt(e.currentStyle.padding);return e.style.left="",e.style.display="none","-"+parseInt((t+n)/2)+"px"},n.fadeIn=function(e,t){var n,o,a;function r(){return a.apply(this,arguments)}+e.style.opacity<1&&(t=t||16,e.style.opacity=0,e.style.display="block",n=+new Date,a=function(){e.style.opacity=+e.style.opacity+(new Date-n)/100,n=+new Date,+e.style.opacity<1&&setTimeout(o,t)},r.toString=function(){return a.toString()},(o=r)()),e.style.display="block"},n.fadeOut=function(e,t){t=t||16,e.style.opacity=1;var n,o=+new Date,a=(n=function(){e.style.opacity=+e.style.opacity-(new Date-o)/100,o=+new Date,0<+e.style.opacity?setTimeout(a,t):e.style.display="none"},r.toString=function(){return n.toString()},r);function r(){return n.apply(this,arguments)}a()},n.fireClick=function(e){var t;"function"==typeof MouseEvent?(t=new MouseEvent("click",{view:w,bubbles:!1,cancelable:!0}),e.dispatchEvent(t)):C.createEvent?((t=C.createEvent("MouseEvents")).initEvent("click",!1,!1),e.dispatchEvent(t)):C.createEventObject?e.fireEvent("onclick"):"function"==typeof e.onclick&&e.onclick()},n.stopEventPropagation=function(e){"function"==typeof e.stopPropagation?(e.stopPropagation(),e.preventDefault()):w.event&&w.event.hasOwnProperty("cancelBubble")&&(w.event.cancelBubble=!0)}},{}],5:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});var c=e("./handle-dom"),d=e("./handle-swal-dom");n.default=function(e,t,n){var e=e||w.event,o=e.keyCode||e.which,a=n.querySelector("button.confirm"),r=n.querySelector("button.cancel"),s=n.querySelectorAll("button[tabindex]");if(-1!==[9,13,32,27].indexOf(o)){for(var l=e.target||e.srcElement,i=-1,u=0;u<s.length;u++)if(l===s[u]){i=u;break}9===o?(l=-1===i?a:i===s.length-1?s[0]:s[i+1],c.stopEventPropagation(e),l.focus(),t.confirmButtonColor&&d.setFocusStyle(l,t.confirmButtonColor)):13===o?"INPUT"===l.tagName&&(l=a).focus():27===o&&!0===t.allowEscapeKey&&c.fireClick(l=r,e)}},t.exports=n.default},{"./handle-dom":4,"./handle-swal-dom":6}],6:[function(e,t,n){function o(e){return e&&e.__esModule?e:{default:e}}function a(){var e=C.createElement("div");for(e.innerHTML=u.default;e.firstChild;)C.body.appendChild(e.firstChild)}Object.defineProperty(n,"__esModule",{value:!0});var r,s=e("./utils"),l=e("./handle-dom"),i=o(e("./default-params")),u=o(e("./injected-html")),c=(r=function(){var e=C.querySelector(".sweet-alert");return e||(a(),e=c()),e},d.toString=function(){return r.toString()},d);function d(){return r.apply(this,arguments)}function f(){var e=c();if(e)return e.querySelector("input")}function p(){return C.querySelector(".sweet-overlay")}function m(e){if(e&&13===e.keyCode)return!1;var t=(e=c()).querySelector(".sa-input-error"),t=(l.removeClass(t,"show"),e.querySelector(".sa-error-container"));l.removeClass(t,"show")}n.sweetAlertInitialize=a,n.getModal=c,n.getOverlay=p,n.getInput=f,n.setFocusStyle=function(e,t){t=s.hexToRgb(t);e.style.boxShadow="0 0 2px rgba("+t+", 0.8), inset 0 0 0 1px rgba(0, 0, 0, 0.05)"},n.openModal=function(e){var t=c();l.fadeIn(p(),10),l.show(t),l.addClass(t,"showSweetAlert"),l.removeClass(t,"hideSweetAlert"),w.previousActiveElement=C.activeElement;t.querySelector("button.confirm").focus(),setTimeout(function(){l.addClass(t,"visible")},500);var n,o=t.getAttribute("data-timer");"null"!==o&&""!==o&&(n=e,t.timeout=setTimeout(function(){(n?"true"===t.getAttribute("data-has-done-function"):null)?n(null):sweetAlert.close()},o))},n.resetInput=function(){var e=c(),t=f();l.removeClass(e,"show-input"),t.value=i.default.inputValue,t.setAttribute("type",i.default.inputType),t.setAttribute("placeholder",i.default.inputPlaceholder),m()},n.resetInputError=m,n.fixVerticalPosition=function(){c().style.marginTop=l.getTopMargin(c())}},{"./default-params":2,"./handle-dom":4,"./injected-html":7,"./utils":9}],7:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});n.default='<div class="sweet-overlay" tabIndex="-1"></div><div class="sweet-alert"><div class="sa-icon sa-error">\n      <span class="sa-x-mark">\n        <span class="sa-line sa-left"></span>\n        <span class="sa-line sa-right"></span>\n      </span>\n    </div><div class="sa-icon sa-warning">\n      <span class="sa-body"></span>\n      <span class="sa-dot"></span>\n    </div><div class="sa-icon sa-info"></div><div class="sa-icon sa-success">\n      <span class="sa-line sa-tip"></span>\n      <span class="sa-line sa-long"></span>\n\n      <div class="sa-placeholder"></div>\n      <div class="sa-fix"></div>\n    </div><div class="sa-icon sa-custom"></div><h2>Title</h2>\n    <p>Text</p>\n    <fieldset>\n      <input type="text" tabIndex="3" />\n      <div class="sa-input-error"></div>\n    </fieldset><div class="sa-error-container">\n      <div class="icon">!</div>\n      <p>Not valid!</p>\n    </div><div class="sa-button-container">\n      <button class="cancel" tabIndex="2">Cancel</button>\n      <div class="sa-confirm-button-container">\n        <button class="confirm" tabIndex="1">OK</button><div class="la-ball-fall">\n          <div></div>\n          <div></div>\n          <div></div>\n        </div>\n      </div>\n    </div></div>',t.exports=n.default},{}],8:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});var u=e("./utils"),c=e("./handle-swal-dom"),d=e("./handle-dom"),f=["error","warning","info","success","input","prompt"];n.default=function(a){var e,t,r=c.getModal(),n=r.querySelector("h2"),o=r.querySelector("p"),s=r.querySelector("button.cancel"),l=r.querySelector("button.confirm");if(n.innerHTML=a.html?a.title:d.escapeHtml(a.title).split("\n").join("<br>"),o.innerHTML=a.html?a.text:d.escapeHtml(a.text||"").split("\n").join("<br>"),a.text&&d.show(o),a.customClass?(d.addClass(r,a.customClass),r.setAttribute("data-custom-class",a.customClass)):(n=r.getAttribute("data-custom-class"),d.removeClass(r,n),r.setAttribute("data-custom-class","")),d.hide(r.querySelectorAll(".sa-icon")),a.type&&!u.isIE8()){var o=function(){for(var e=!1,t=0;t<f.length;t++)if(a.type===f[t]){e=!0;break}if(!e)return logStr("Unknown alert type: "+a.type),{v:!1};var n=S,o=(-1!==["success","error","warning","info"].indexOf(a.type)&&(n=r.querySelector(".sa-icon.sa-"+a.type),d.show(n)),c.getInput());switch(a.type){case"success":d.addClass(n,"animate"),d.addClass(n.querySelector(".sa-tip"),"animateSuccessTip"),d.addClass(n.querySelector(".sa-long"),"animateSuccessLong");break;case"error":d.addClass(n,"animateErrorIcon"),d.addClass(n.querySelector(".sa-x-mark"),"animateXMark");break;case"warning":d.addClass(n,"pulseWarning"),d.addClass(n.querySelector(".sa-body"),"pulseWarningIns"),d.addClass(n.querySelector(".sa-dot"),"pulseWarningIns");break;case"input":case"prompt":o.setAttribute("type",a.inputType),o.value=a.inputValue,o.setAttribute("placeholder",a.inputPlaceholder),d.addClass(r,"show-input"),setTimeout(function(){o.focus(),o.addEventListener("keyup",swal.resetInputError)},400)}}();if("object"==typeof o)return o.v}a.imageUrl&&((n=r.querySelector(".sa-icon.sa-custom")).style.backgroundImage="url("+a.imageUrl+")",d.show(n),e=o=80,a.imageSize&&(i=(t=a.imageSize.toString().split("x"))[0],t=t[1],i&&t?(o=i,e=t):logStr("Parameter imageSize expects value with format WIDTHxHEIGHT, got "+a.imageSize)),n.setAttribute("style",n.getAttribute("style")+"width:"+o+"px; height:"+e+"px")),r.setAttribute("data-has-cancel-button",a.showCancelButton),a.showCancelButton?s.style.display="inline-block":d.hide(s),r.setAttribute("data-has-confirm-button",a.showConfirmButton),a.showConfirmButton?l.style.display="inline-block":d.hide(l),a.cancelButtonText&&(s.innerHTML=d.escapeHtml(a.cancelButtonText)),a.confirmButtonText&&(l.innerHTML=d.escapeHtml(a.confirmButtonText)),a.confirmButtonColor&&(l.style.backgroundColor=a.confirmButtonColor,l.style.borderLeftColor=a.confirmLoadingButtonColor,l.style.borderRightColor=a.confirmLoadingButtonColor,c.setFocusStyle(l,a.confirmButtonColor)),r.setAttribute("data-allow-outside-click",a.allowOutsideClick);var i=!!a.doneFunction;r.setAttribute("data-has-done-function",i),a.animation?"string"==typeof a.animation?r.setAttribute("data-animation",a.animation):r.setAttribute("data-animation","pop"):r.setAttribute("data-animation","none"),r.setAttribute("data-timer",a.timer)},t.exports=n.default},{"./handle-dom":4,"./handle-swal-dom":6,"./utils":9}],9:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});n.extend=function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},n.hexToRgb=function(e){e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return e?parseInt(e[1],16)+", "+parseInt(e[2],16)+", "+parseInt(e[3],16):null},n.isIE8=function(){return w.attachEvent&&!w.addEventListener},n.logStr=function(e){w.console&&w.console.log("SweetAlert: "+e)},n.colorLuminance=function(e,t){(e=String(e).replace(/[^0-9a-f]/gi,"")).length<6&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),t=t||0;for(var n,o="#",a=0;a<3;a++)n=parseInt(e.substr(2*a,2),16),o+=("00"+(n=Math.round(Math.min(Math.max(0,n+n*t),255)).toString(16))).substr(n.length);return o}},{}]},{},[1]),"function"==typeof define&&define.amd?define(function(){return sweetAlert}):"undefined"!=typeof module&&module.exports&&(module.exports=sweetAlert)}(window,document);

    在博客根目录往下找到\themes\butterfly\source\css文件夹,新建sweetalert.css

    1
    2
    3
    4
    5
    .sweet-alert,.sweet-overlay{position:fixed;display:none}body.stop-scrolling{height:100%;overflow:hidden}.sweet-overlay{background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";background-color:rgba(0,0,0,.4);left:0;right:0;top:0;bottom:0;z-index:10000}.sweet-alert{background-color:#fff;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;width:478px;padding:17px;border-radius:5px;text-align:center;left:50%;top:50%;margin-left:-256px;margin-top:-200px;overflow:hidden;z-index:99999}@media all and (max-width:540px){.sweet-alert{width:auto;margin-left:0;margin-right:0;left:15px;right:15px}}.sweet-alert h2{color:#575757;font-size:30px;text-align:center;font-weight:600;text-transform:none;position:relative;margin:25px 0;padding:0;line-height:40px;display:block}.sweet-alert p{color:#797979;font-size:16px;font-weight:300;position:relative;text-align:inherit;float:none;margin:0;padding:0;line-height:normal}.sweet-alert fieldset{border:none;position:relative}.sweet-alert .sa-error-container{background-color:#f1f1f1;margin-left:-17px;margin-right:-17px;overflow:hidden;padding:0 10px;max-height:0;webkit-transition:padding .15s,max-height .15s;transition:padding .15s,max-height .15s}.sweet-alert .sa-error-container.show{padding:10px 0;max-height:100px;webkit-transition:padding .2s,max-height .2s;transition:padding .25s,max-height .25s}.sweet-alert .sa-error-container .icon{display:inline-block;width:24px;height:24px;border-radius:50%;background-color:#ea7d7d;color:#fff;line-height:24px;text-align:center;margin-right:3px}.sweet-alert .sa-error-container p{display:inline-block}.sweet-alert .sa-input-error{position:absolute;top:29px;right:26px;width:20px;height:20px;opacity:0;-webkit-transform:scale(.5);transform:scale(.5);-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transition:all .1s;transition:all .1s}.sweet-alert .sa-input-error::after,.sweet-alert .sa-input-error::before{content:"";width:20px;height:6px;background-color:#f06e57;border-radius:3px;position:absolute;top:50%;margin-top:-4px;left:50%;margin-left:-9px}.sweet-alert .sa-input-error::before{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .sa-input-error::after{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .sa-input-error.show{opacity:1;-webkit-transform:scale(1);transform:scale(1)}.sweet-alert input{width:100%;box-sizing:border-box;border-radius:3px;border:1px solid #d7d7d7;height:43px;margin-top:10px;margin-bottom:17px;font-size:18px;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);padding:0 12px;display:none;-webkit-transition:all .3s;transition:all .3s}.sweet-alert input:focus{outline:0;box-shadow:0 0 3px #c4e6f5;border:1px solid #b4dbed}.sweet-alert input:focus::-moz-placeholder{transition:opacity .3s 30ms ease;opacity:.5}.sweet-alert input:focus:-ms-input-placeholder{transition:opacity .3s 30ms ease;opacity:.5}.sweet-alert input:focus::-webkit-input-placeholder{transition:opacity .3s 30ms ease;opacity:.5}.sweet-alert input::-moz-placeholder{color:#bdbdbd}.sweet-alert input:-ms-input-placeholder{color:#bdbdbd}.sweet-alert input::-webkit-input-placeholder{color:#bdbdbd}.sweet-alert.show-input input{display:block}.sweet-alert .sa-confirm-button-container{display:inline-block;position:relative}.sweet-alert .la-ball-fall{position:absolute;left:50%;top:50%;margin-left:-27px;margin-top:4px;opacity:0;visibility:hidden}.sweet-alert button{background-color:#8CD4F5;color:#fff;border:none;box-shadow:none;font-size:17px;font-weight:500;-webkit-border-radius:4px;border-radius:5px;padding:10px 32px;margin:26px 5px 0;cursor:pointer}.sweet-alert button:focus{outline:0;box-shadow:0 0 2px rgba(128,179,235,.5),inset 0 0 0 1px rgba(0,0,0,.05)}.sweet-alert button:hover{background-color:#7ecff4}.sweet-alert button:active{background-color:#5dc2f1}.sweet-alert button.cancel{background-color:#C1C1C1}.sweet-alert button.cancel:hover{background-color:#b9b9b9}.sweet-alert button.cancel:active{background-color:#a8a8a8}.sweet-alert button.cancel:focus{box-shadow:rgba(197,205,211,.8) 0 0 2px,rgba(0,0,0,.0470588) 0 0 0 1px inset!important}.sweet-alert button[disabled]{opacity:.6;cursor:default}.sweet-alert button.confirm[disabled]{color:transparent}.sweet-alert button.confirm[disabled]~.la-ball-fall{opacity:1;visibility:visible;transition-delay:0s}.sweet-alert button::-moz-focus-inner{border:0}.sweet-alert[data-has-cancel-button=false] button{box-shadow:none!important}.sweet-alert[data-has-confirm-button=false][data-has-cancel-button=false]{padding-bottom:40px}.sweet-alert .sa-icon{width:80px;height:80px;border:4px solid gray;-webkit-border-radius:40px;border-radius:50%;margin:20px auto;padding:0;position:relative;box-sizing:content-box}.sweet-alert .sa-icon.sa-error{border-color:#F27474}.sweet-alert .sa-icon.sa-error .sa-x-mark{position:relative;display:block}.sweet-alert .sa-icon.sa-error .sa-line{position:absolute;height:5px;width:47px;background-color:#F27474;display:block;top:37px;border-radius:2px}.sweet-alert .sa-icon.sa-error .sa-line.sa-left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.sweet-alert .sa-icon.sa-error .sa-line.sa-right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}.sweet-alert .sa-icon.sa-warning{border-color:#F8BB86}.sweet-alert .sa-icon.sa-warning .sa-body{position:absolute;width:5px;height:47px;left:50%;top:10px;-webkit-border-radius:2px;border-radius:2px;margin-left:-2px;background-color:#F8BB86}.sweet-alert .sa-icon.sa-warning .sa-dot{position:absolute;width:7px;height:7px;-webkit-border-radius:50%;border-radius:50%;margin-left:-3px;left:50%;bottom:10px;background-color:#F8BB86}.sweet-alert .sa-icon.sa-info::after,.sweet-alert .sa-icon.sa-info::before{content:"";background-color:#C9DAE1;position:absolute}.sweet-alert .sa-icon.sa-info{border-color:#C9DAE1}.sweet-alert .sa-icon.sa-info::before{width:5px;height:29px;left:50%;bottom:17px;border-radius:2px;margin-left:-2px}.sweet-alert .sa-icon.sa-info::after{width:7px;height:7px;border-radius:50%;margin-left:-3px;top:19px}.sweet-alert .sa-icon.sa-success{border-color:#A5DC86}.sweet-alert .sa-icon.sa-success::after,.sweet-alert .sa-icon.sa-success::before{content:'';position:absolute;width:60px;height:120px;background:#fff}.sweet-alert .sa-icon.sa-success::before{-webkit-border-radius:120px 0 0 120px;border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.sweet-alert .sa-icon.sa-success::after{-webkit-border-radius:0 120px 120px 0;border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px}.sweet-alert .sa-icon.sa-success .sa-placeholder{width:80px;height:80px;border:4px solid rgba(165,220,134,.2);-webkit-border-radius:40px;border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.sweet-alert .sa-icon.sa-success .sa-fix{width:5px;height:90px;background-color:#fff;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .sa-icon.sa-success .sa-line{height:5px;background-color:#A5DC86;display:block;border-radius:2px;position:absolute;z-index:2}.sweet-alert .sa-icon.sa-success .sa-line.sa-tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .sa-icon.sa-success .sa-line.sa-long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .sa-icon.sa-custom{background-size:contain;border-radius:0;border:none;background-position:center center;background-repeat:no-repeat}@-webkit-keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}45%{transform:scale(1.05);-webkit-transform:scale(1.05)}80%{transform:scale(.95);-webkit-transform:scale(.95)}100%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}45%{transform:scale(1.05);-webkit-transform:scale(1.05)}80%{transform:scale(.95);-webkit-transform:scale(.95)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-webkit-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@-webkit-keyframes slideFromTop{0%{top:0}100%{top:50%}}@keyframes slideFromTop{0%{top:0}100%{top:50%}}@-webkit-keyframes slideToTop{0%{top:50%}100%{top:0}}@keyframes slideToTop{0%{top:50%}100%{top:0}}@-webkit-keyframes slideFromBottom{0%{top:70%}100%{top:50%}}@keyframes slideFromBottom{0%{top:70%}100%{top:50%}}@-webkit-keyframes slideToBottom{0%{top:50%}100%{top:70%}}@keyframes slideToBottom{0%{top:50%}100%{top:70%}}.showSweetAlert[data-animation=pop]{-webkit-animation:showSweetAlert .3s;animation:showSweetAlert .3s}.showSweetAlert[data-animation=none]{-webkit-animation:none;animation:none}.showSweetAlert[data-animation=slide-from-top]{-webkit-animation:slideFromTop .3s;animation:slideFromTop .3s}.showSweetAlert[data-animation=slide-from-bottom]{-webkit-animation:slideFromBottom .3s;animation:slideFromBottom .3s}.hideSweetAlert[data-animation=pop]{-webkit-animation:hideSweetAlert .2s;animation:hideSweetAlert .2s}.hideSweetAlert[data-animation=none]{-webkit-animation:none;animation:none}.hideSweetAlert[data-animation=slide-from-top]{-webkit-animation:slideToTop .4s;animation:slideToTop .4s}.hideSweetAlert[data-animation=slide-from-bottom]{-webkit-animation:slideToBottom .3s;animation:slideToBottom .3s}@-webkit-keyframes animateSuccessTip{0%,54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@keyframes animateSuccessTip{0%,54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@-webkit-keyframes animateSuccessLong{0%,65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@keyframes animateSuccessLong{0%,65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@-webkit-keyframes rotatePlaceholder{0%,5%{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}100%,12%{transform:rotate(-405deg);-webkit-transform:rotate(-405deg)}}@keyframes rotatePlaceholder{0%,5%{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}100%,12%{transform:rotate(-405deg);-webkit-transform:rotate(-405deg)}}.animateSuccessTip{-webkit-animation:animateSuccessTip .75s;animation:animateSuccessTip .75s}.animateSuccessLong{-webkit-animation:animateSuccessLong .75s;animation:animateSuccessLong .75s}.sa-icon.sa-success.animate::after{-webkit-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}@-webkit-keyframes animateErrorIcon{0%{transform:rotateX(100deg);-webkit-transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);-webkit-transform:rotateX(0);opacity:1}}@keyframes animateErrorIcon{0%{transform:rotateX(100deg);-webkit-transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);-webkit-transform:rotateX(0);opacity:1}}.animateErrorIcon{-webkit-animation:animateErrorIcon .5s;animation:animateErrorIcon .5s}@-webkit-keyframes animateXMark{0%,50%{transform:scale(.4);-webkit-transform:scale(.4);margin-top:26px;opacity:0}80%{transform:scale(1.15);-webkit-transform:scale(1.15);margin-top:-6px}100%{transform:scale(1);-webkit-transform:scale(1);margin-top:0;opacity:1}}@keyframes animateXMark{0%,50%{transform:scale(.4);-webkit-transform:scale(.4);margin-top:26px;opacity:0}80%{transform:scale(1.15);-webkit-transform:scale(1.15);margin-top:-6px}100%{transform:scale(1);-webkit-transform:scale(1);margin-top:0;opacity:1}}.animateXMark{-webkit-animation:animateXMark .5s;animation:animateXMark .5s}@-webkit-keyframes pulseWarning{0%{border-color:#F8D486}100%{border-color:#F8BB86}}@keyframes pulseWarning{0%{border-color:#F8D486}100%{border-color:#F8BB86}}.pulseWarning{-webkit-animation:pulseWarning .75s infinite alternate;animation:pulseWarning .75s infinite alternate}@-webkit-keyframes pulseWarningIns{0%{background-color:#F8D486}100%{background-color:#F8BB86}}@keyframes pulseWarningIns{0%{background-color:#F8D486}100%{background-color:#F8BB86}}.pulseWarningIns{-webkit-animation:pulseWarningIns .75s infinite alternate;animation:pulseWarningIns .75s infinite alternate}@-webkit-keyframes rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.sweet-alert .sa-icon.sa-error .sa-line.sa-left{-ms-transform:rotate(45deg)\9}.sweet-alert .sa-icon.sa-error .sa-line.sa-right{-ms-transform:rotate(-45deg)\9}.sweet-alert .sa-icon.sa-success{border-color:transparent\9}.sweet-alert .sa-icon.sa-success .sa-line.sa-tip{-ms-transform:rotate(45deg)\9}.sweet-alert .sa-icon.sa-success .sa-line.sa-long{-ms-transform:rotate(-45deg)\9}/*!
    * Load Awesome v1.1.0 (http://github.danielcardoso.net/load-awesome/)
    * Copyright 2015 Daniel Cardoso <@DanielCardoso>
    * Licensed under MIT
    */.la-ball-fall,.la-ball-fall>div{position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.la-ball-fall{display:block;font-size:0;color:#fff;width:54px;height:18px}.la-ball-fall.la-dark{color:#333}.la-ball-fall>div{display:inline-block;float:none;background-color:currentColor;border:0 solid currentColor;width:10px;height:10px;margin:4px;border-radius:100%;opacity:0;-webkit-animation:ball-fall 1s ease-in-out infinite;-moz-animation:ball-fall 1s ease-in-out infinite;-o-animation:ball-fall 1s ease-in-out infinite;animation:ball-fall 1s ease-in-out infinite}.la-ball-fall>div:nth-child(1){-webkit-animation-delay:-.2s;-moz-animation-delay:-.2s;-o-animation-delay:-.2s;animation-delay:-.2s}.la-ball-fall>div:nth-child(2){-webkit-animation-delay:-.1s;-moz-animation-delay:-.1s;-o-animation-delay:-.1s;animation-delay:-.1s}.la-ball-fall>div:nth-child(3){-webkit-animation-delay:0s;-moz-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s}.la-ball-fall.la-sm{width:26px;height:8px}.la-ball-fall.la-sm>div{width:4px;height:4px;margin:2px}.la-ball-fall.la-2x{width:108px;height:36px}.la-ball-fall.la-2x>div{width:20px;height:20px;margin:8px}.la-ball-fall.la-3x{width:162px;height:54px}.la-ball-fall.la-3x>div{width:30px;height:30px;margin:12px}@-webkit-keyframes ball-fall{0%{opacity:0;-webkit-transform:translateY(-145%);transform:translateY(-145%)}10%,90%{opacity:.5}20%,80%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(145%);transform:translateY(145%)}}@-moz-keyframes ball-fall{0%{opacity:0;-moz-transform:translateY(-145%);transform:translateY(-145%)}10%,90%{opacity:.5}20%,80%{opacity:1;-moz-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-moz-transform:translateY(145%);transform:translateY(145%)}}@-o-keyframes ball-fall{0%{opacity:0;-o-transform:translateY(-145%);transform:translateY(-145%)}10%,90%{opacity:.5}20%,80%{opacity:1;-o-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-o-transform:translateY(145%);transform:translateY(145%)}}@keyframes ball-fall{0%{opacity:0;-webkit-transform:translateY(-145%);-moz-transform:translateY(-145%);-o-transform:translateY(-145%);transform:translateY(-145%)}10%,90%{opacity:.5}20%,80%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(145%);-moz-transform:translateY(145%);-o-transform:translateY(145%);transform:translateY(145%)}}
  2. 使用

    在主题配置文件 _config.butterfly.ymlinject.head 引入样式

    1
    2
    3
    4
    5
    6
    7
    # Inject
    inject:
    head:
    - <link rel="stylesheet" href="/css/sweetalert.css"> # 欢迎弹窗
    bottom:
    - <script src="/js/sweetalert.js"></script> # 欢迎弹窗
    - <script type="text/javascript" src ="/js/welcome.js" ></script> # 欢迎弹窗

添加信笺样式留言板

查看步骤
  1. [Blogroot]运行指令

    1
    npm install hexo-butterfly-envelope --save
  2. 在站点配置文件或者主题配置文件添加配置项(对,两者任一均可。但不要都写)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # envelope_comment
    # see https://akilar.top/posts/e2d3c450/
    envelope_comment:
    enable: true #控制开关
    custom_pic:
    cover: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg #信笺头部图片
    line: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png #信笺底部图片
    beforeimg: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png # 信封前半部分
    afterimg: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png # 信封后半部分
    message: #信笺正文,多行文本,写法如下
    - 有什么想问的?
    - 有什么想说的?
    - 有什么想吐槽的?
    - 哪怕是有什么想吃的,都可以告诉我哦~
    bottom: 自动书记人偶竭诚为您服务! #仅支持单行文本
    height: #1050px,信封划出的高度
    path: #【可选】comments 的路径名称。默认为 comments,生成的页面为 comments/index.html
    front_matter: #【可选】comments页面的 front_matter 配置
    title: 留言板
    comments: true

    注意路径path:comments部分要和菜单menu选项中的留言板设置对应

自定义错误页面

添加贡献日历

在线聊天功能

基于 Butterfly 的外挂标签引入

参考

排名不分先后,有一些忘记统一在这里记录了