Hexo 实现实时预览编辑

点击下拉查看具体内容

参考自:Hexo 实现实时预览编辑 | 木头的博客 (mutoe.com)

主要在项目目录下安装 hexo-browsersync 插件

1
npm install hexo-browsersync --save

然后运行 hexo server, 看到以下内容就说明启动成功啦.【针对_config.Butterfly.yml需要重启hexo s】

1
2
3
4
5
6
7
8
[Browsersync] Access URLs:
----------------------------------
UI: http://localhost:3001
----------------------------------
UI External: http://localhost:3001
----------------------------------
INFO Start processing
INFO Hexo is running at http://localhost:4000/ . Press Ctrl+C to stop.

解决hexo引入图床,手机和web不显示图片的问题

点击下拉查看具体内容

这里以Butterfly主题为例

在butterfly\layout\includes\head.pug中【其中加号为需要添加的】

1
2
3
4
5
meta(name="author" content=pageAuthor)
meta(name="copyright" content=pageCopyright)
meta(name ="format-detection" content="telephone=no")
meta(name="theme-color" content=themeColor)
+ meta(name="referrer" content="no-referrer")

背景音乐添加

点击下拉查看具体内容

参考自hexo-butterfly魔改记录大全 | Black Flies (yyyzyyyz.cn)

这里参考作者的全局吸底Aplayer教程,为方便后续自己查阅,特摘抄出来。

首先安装hexo-tag-aplayer插件,官方github;

博客根目录安装:

1
npm install --save hexo-tag-aplayer

由于需要全局都插入aplayer和meting资源,为了防止插入重复的资源,需要把asset_inject设为false

在hexo的配置文件中

1
2
3
aplayer:
meting: true
asset_inject: false

在主题配置文件中,enable设为true和per_page设为true

1
2
3
4
# Inject the css and script (aplayer/meting)
aplayerInject:
enable: true
per_page: true

在跳转页面时不关闭音乐,需要开启pjax

1
2
3
4
5
6
7
8
# Pjax
# It may contain bugs and unstable, give feedback when you find the bugs.
# https://github.com/MoOx/pjax
pjax:
enable: true
exclude:
# - xxxx
# - xxxx

然后把代码插入到页脚中

1
2
3
4
 bottom:
# - <script src="xxxx"></script>
#require APlayer
+ - <div class="aplayer no-destroy" data-id="6693541741" data-server="netease" data-type="playlist" data-fixed="true" data-autoplay="true" data-lrcType="-1"> </div>

butterfly导航栏修改方案

点击下拉查看具体内容

新建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
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
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
#nav a:hover {
background: var(--sevene-main);
transition: 0.3s;
}

#nav-totop:hover .totopbtn i {
opacity: 1;
}
#nav-totop #percent {
font-size: 12px;
background: var(--sevene-white);
color: var(--sevene-main);
width: 25px;
height: 25px;
border-radius: 35px;
display: flex;
justify-content: center;
align-items: center;
transition: 0.3s;
}
.nav-fixed #nav-totop #percent,
.page #nav-totop #percent {
background: var(--font-color);
color: var(--card-bg);
}

#nav-totop {
width: 35px;
}
#page-header:not(.is-top-bar) #percent {
transition: 0.3s;
}
#page-header:not(.is-top-bar) #nav-totop {
width: 0;
opacity: 0;
transition: width 0.3s, opacity 0.2s;
margin-left: 0 !important;
}
#nav-totop #percent {
font-weight: 700;
}
#nav-totop:hover #percent {
opacity: 0;
transform: scale(1.5);
font-weight: 700;
}
.nav-fixed #nav-totop #percent,
.page #nav-totop #percent {
font-size: 13px;
}
#page-header #nav #nav-right div {
margin-left: 0.5rem;
padding: 0;
}

#nav-totop {
display: flex;
align-items: center;
justify-content: center;
transition: 0.3s;
}
.nav-button {
cursor: pointer;
}
div#menus {
display: flex;
align-items: center;
}
#page-header #nav .nav-button a {
height: 35px;
width: 35px;
display: flex;
align-items: center;
justify-content: center;
}

#nav .site-page {
padding-bottom: 0px;
}
#nav *::after {
background-color: transparent !important;
}

/* 顶栏修改 */
#nav .menus_items .menus_item .menus_item_child li:hover a {
color: white !important;
}

#nav .menus_items .menus_item .menus_item_child li {
margin: 6px;
border-radius: 5px !important;
transition: all 0.3s;
}

#site-name,
.shuoshuo {
white-space: nowrap;
overflow: hidden;
}
#site-name {
padding: 0 8px;
position: relative;
}
#site-name *:not(i):hover {
display: none !important;
}
#blog_name #site-name:hover::after {
opacity: 1;
transform: scale(1.01);
}
#blog_name #site-name::after {
opacity: 0;
background-color: var(--lyx-theme) !important;
border-radius: 8px;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
-ms-border-radius: 8px;
-o-border-radius: 8px;
transition: 0.3s;
-webkit-transition: 0.3s;
-moz-transition: 0.3s;
-ms-transition: 0.3s;
-o-transition: 0.3s;
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
content: '\f015';
box-shadow: 0 0 5px var(--lyx-theme);
font-family: 'Font Awesome 6 Free';
text-align: center;
color: white;
}
#site-name i {
position: absolute;
top: 50%;
left: 50% !important;
transform: translate(-50%, -50%);
left: 0;
opacity: 0;
}
#site-name:hover i {
opacity: 1;
}

/* 横向排布子菜单 */
#nav .menus_items .menus_item .menus_item_child li {
display: inline-block;
}
/* 圆角隐藏 */
ul.menus_item_child {
overflow: hidden;
border-radius: 5px;
}

/* 一级菜单居中 */
#nav .menus_items {
position: absolute;
width: fit-content;
left: 50%;
transform: translateX(-50%);
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 60px;
}

#nav .menus_items .menus_item:hover .menus_item_child {
display: block;
transform: translateX(-50%);
right: auto;
left: auto !important;
}
#nav .menus_items .menus_item:hover {
padding: 0 5px 27px 5px !important;
margin-bottom: -15px !important;
}
#nav .menus_items .menus_item .menus_item_child {
top: 44px;
}

@media screen and (min-width: 768px) {
.page .menus_item:hover > a.site-page {
color: var(--sevene-white) !important;
background: var(--sevene-main);
transition: 0.3s;
box-shadow: var(--sevene-shadow-main);
}
}

#nav .menus_items .menus_item:hover .menus_item_child {
padding: 6px 4px;
box-sizing: content-box;
line-height: 35px;
}

#nav .menus_items .menus_item .menus_item_child li {
margin: 0 3px;
}
#nav .menus_items .menus_item .menus_item_child li a {
padding: 0px 16px;
}

.nav-fixed #nav {
transform: translateY(58px) !important;
-webkit-transform: translateY(58px) !important;
-moz-transform: translateY(58px) !important;
-ms-transform: translateY(58px) !important;
-o-transform: translateY(58px) !important;
}
#nav {
padding: 0 calc((100% - 1420px) / 2);
transition: 0.3s;
background: var(--sevene-maskbgdeep);
backdrop-filter: saturate(180%) blur(20px);
transition: none !important;
-webkit-transition: none !important;
-moz-transition: none !important;
-ms-transition: none !important;
-o-transition: none !important;
}

#nav a {
border-radius: 8px;
color: var(--font-color);
}
.page #nav a:hover {
color: var(--sevene-white) !important;
background: var(--sevene-main);
transition: 0.3s;
box-shadow: var(--sevene-shadow-main);
}

#menus > div.menus_items > div > a {
letter-spacing: 0.3rem;
font-weight: 700;
padding: 0em 0.3em 0em 0.5em;
height: 35px;
}
#nav .menus_items .menus_item {
padding: 0 5px;
display: flex;
flex-direction: column;
margin: auto;
align-items: center;
}

#menus > div.menus_items > div > a {
line-height: 35px;
}

#page-header #nav a:hover,
#page-header.nav-fixed #nav a:hover,
#page-header.nav-fixed #nav #site-name:hover,
#page-header.nav-fixed #nav #toggle-menu:hover {
color: var(--sevene-white);
font-weight: bold;
}
#page-header.nav-fixed #nav a, #page-header.nav-fixed #nav #site-name, #page-header.nav-fixed #nav #toggle-menu {
font-weight: bold;
}
#nav-totop .totopbtn i {
position: absolute;
display: flex;
opacity: 0;
}
#page-name::before {
font-size: 18px;
position: absolute;
width: 100%;
height: 100%;
border-radius: 8px;
color: white !important;
top: 0;
left: 0;
content: '回到顶部';
background-color: var(--lyx-theme);
transition: all 0.3s;
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
-ms-transition: all 0.3s;
-o-transition: all 0.3s;
opacity: 0;
box-shadow: 0 0 3px var(--lyx-theme);
line-height: 45px; /*如果垂直位置不居中可以微调此值,也可以删了*/
}
#page-name:hover:before {
opacity: 1;
}
#name-container {
transition: all 0.3s;
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
-ms-transition: all 0.3s;
-o-transition: all 0.3s;
}
#name-container:hover {
transform: translateX(-50%) scale(1.03);
}
#page-name {
position: relative;
padding: 10px 30px;
}

center#name-container {
position: absolute;
width: 100%;
left: 50%;
transform: translateX(-50%);
font-family: 'ZhuZiAYuanJWD';
}
.nav-fixed.nav-visible #name-container {
top: 60px;
transition: 0.3s;
}
.nav-fixed.nav-visible #menus .menus_items {
bottom: -0px;
transition: 0.3s;
line-height: 60px;
}
.nav-fixed #menus .menus_items {
bottom: 60px;
transition: 0.3s;
}
.nav-fixed #name-container {
top: 15%;
transition: 0.3s;
}
#name-container {
bottom: 60px;
}

.mask-name-container {
width: 1200px;
height: 100%;
position: absolute;
overflow: hidden;
left: 50%;
transform: translateX(-50%);
}

@media screen and (max-width: 768px) {
.mask-name-container {
width: 600px;
}
}
@media screen and (max-width: 500px) {
.mask-name-container {
display: none;
}
}
#sidebar #sidebar-menus .menus_items .site-page:hover {
color: var(--sevene-white);
border-radius: var(--sevene-border-radius);
}
#nav .menus_items .menus_item > a > i:last-child {
display: none;
}
#nav #search-button {
font-size: 1.3em;
}

#page-header.not-top-img #nav .back-home-button {
color: var(--sevene-fontcolor);
}
@media screen and (min-width: 900px) {
#nav .back-home-button:hover {
box-shadow: var(--sevene-shadow-main);
}
}

.back-home-button:hover {
background: var(--sevene-main);
color: var(--sevene-white) !important;
}
.back-home-button {
display: flex;
width: 35px;
height: 35px;
padding: 0 !important;
align-items: center;
justify-content: center;
margin-right: 4px;
transition: 0.3s;
border-radius: 8px;
color: var(--sevene-white);
}

.back-home-button:hover .back-menu-list-groups {
display: flex;
opacity: 1;
transition: 0.3s;
top: 55px;
pointer-events: auto;
left: 0;
}
.back-home-button .back-menu-list-groups {
position: absolute;
top: 65px;
left: 0;
background: var(--sevene-card-bg);
border-radius: 12px;
border: var(--style-border);
flex-direction: column;
font-size: 12px;
color: var(--sevene-secondtext);
box-shadow: var(--sevene-shadow-border);
transition: 0s;
opacity: 0;
pointer-events: none;
}

.back-home-button .back-menu-list-group {
display: flex;
flex-direction: column;
}
.back-home-button .back-menu-list-group .back-menu-list-title {
margin: 8px 0 0 16px;
transition: 0.3s;
}
.back-home-button .back-menu-list {
display: flex;
flex-direction: column;
}
.back-home-button .back-menu-list::before {
position: absolute;
top: -22px;
left: 0px;
width: 100%;
height: 25px;
content: '';
}

.back-home-button .back-menu-list-group:hover .back-menu-list-title {
color: var(--sevene-main);
}
.back-home-button .back-menu-list-groups:hover {
border: var(--style-border-hover);
}
.back-home-button .back-menu-list .back-menu-item {
display: flex;
align-items: center;
margin: 4px 8px;
padding: 4px 8px !important;
transition: 0.3s;
border-radius: 8px;
}
.back-home-button .back-menu-list .back-menu-item .back-menu-item-text {
font-size: var(--global-font-size);
margin-left: 0.5rem;
color: var(--sevene-fontcolor);
white-space: nowrap;
}
#nav #blog_name {
flex-wrap: nowrap;
height: 60px;
display: flex;
align-items: center;
/* z-index: 102; */
transition: 0.3s;
}
.back-home-button .back-menu-list .back-menu-item .back-menu-item-icon {
width: 24px;
height: 24px;
border-radius: 24px;
background: var(--sevene-secondbg);
}
#page-header #nav .back-home-button {
color: var(--sevene-fontcolor);
cursor: pointer;
position: relative;
}

.page #nav a:hover {
color: var(--sevene-white) !important;
background: var(--sevene-main);
transition: 0.3s;
box-shadow: var(--sevene-shadow-main);
}
@media screen and (min-width: 1300px) {
#nav a:hover {
transform: scale(1.03);
}
}
.back-home-button .back-menu-list .back-menu-item:hover .back-menu-item-text {
color: var(--sevene-white);
}
.back-menu-item-icon.loading img {
width: 25px;
}
[data-theme="light"]
.back-home-button .back-menu-list-groups{
/*控制左上角的菜单的颜色背景*/
--sevene-card-bg: rgb(255,255,255,0.8);
}
[data-theme="dark"]
.back-home-button .back-menu-list-groups{
/*控制左上角的菜单的颜色背景*/
--sevene-card-bg: rgb(1,1,1,0.8);
}
[data-theme="light"]
#rightMenu .rightMenu-group .rightMenu-item{
color: rgb(1, 1, 1);
}
[data-theme="dark"]
#rightMenu .rightMenu-group .rightMenu-item{
color: white;
}
:root{
--lyx-theme:#00FA9A; /*我的主题色*/
/*控制左上角的菜单的颜色字体*/
--sevene-white:rgb(255, 255, 255);
/*控制左上角的菜单的选择时颜色背景*/
--sevene-main:rgb(0, 250, 154);
--sevene-shadow-main:rgb(31, 95, 158);
--sevene-maskbgdeep:rgb(255, 9, 9);
--sevene-border-radius:30px;
}

新建js

1
2
3
4
5
6
7
8
9
10
11
// 返回顶部 显示网页阅读进度
window.onscroll = percent;// 执行函数
// 页面百分比
function percent() {
let a = document.documentElement.scrollTop || window.pageYOffset, // 卷去高度
b = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight) - document.documentElement.clientHeight, // 整个网页高度 减去 可视高度
result = Math.round(a / b * 100), // 计算百分比
btn = document.querySelector("#percent"); // 获取图标
result<=99||(result=99),btn.innerHTML=result
}
document.getElementById("page-name").innerText=document.title.split(" | 七鳄の学习格")[0];

修改 themes/butterfly/source/js/main.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
  window.scrollCollect = () => {
return btf.throttle(function (e) {
const currentTop = window.scrollY || document.documentElement.scrollTop
const isDown = scrollDirection(currentTop)
if (currentTop > 56) {
+ $header.classList.add('is-top-bar')
if (isDown) {
if ($header.classList.contains('nav-visible')) $header.classList.remove('nav-visible')
if (isChatBtnShow && isChatShow === true) {
chatBtnHide()
isChatShow = false
}
} else {
if (!$header.classList.contains('nav-visible')) $header.classList.add('nav-visible')
if (isChatBtnHide && isChatShow === false) {
chatBtnShow()
isChatShow = true
}
}
$header.classList.add('nav-fixed')
if (window.getComputedStyle($rightside).getPropertyValue('opacity') === '0') {
$rightside.style.cssText = 'opacity: 0.8; transform: translateX(-58px)'
}
} else {
if (currentTop === 0) {
- $header.classList.remove('nav-fixed', 'nav-visible')
+ $header.classList.remove('is-top-bar')
}
$rightside.style.cssText = "opacity: ''; transform: ''"
}

if (document.body.scrollHeight <= innerHeight) {
$rightside.style.cssText = 'opacity: 0.8; transform: translateX(-58px)'
}
}, 200)()
}

修改 themes/butterfly/layout/includes/header/index.pug

其中nav-visible可以控制默认显示的是站点标题还是导航栏菜单。

1
2
3
4
5
6
7
8
9
  if top_img !== false
- var imgSource = top_img && top_img.indexOf('/') !== -1 ? `background-image: url('${url_for(top_img)}')` : `background: ${top_img}`
- var bg_img = top_img ? imgSource : ''
- var site_title = page.title || page.tag || page.category || config.title
- - var isHomeClass = is_home() ? 'full_page' : 'not-home-page'
+ - var isHomeClass = is_home() ? 'full_page nav-fixed nav-visible' : 'not-home-page'
- is_post() ? isHomeClass = 'post-bg' : isHomeClass
else
- var isHomeClass = 'not-top-img'

nav.pug

替换themes/butterfly/layout/includes/header/nav.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
45
46
47
- const { darkmode } = theme
nav#nav
span#blog_name
.back-home-button(tabindex='-1')
i.back-home-button-icon.fas.fa-grip-vertical
.back-menu-list-groups
.back-menu-list-group
.back-menu-list-title 网页
.back-menu-list
a.back-menu-item(href='/', title='前往博客主页', target='_blank', one-link-mark='yes')
img.back-menu-item-icon(src='https://image.anzhiy.cn/adminuploads/1/2022/09/05/6315ec9737ac4.png')
span.back-menu-item-text 博客
a.back-menu-item(href='https://www.cloud.anzhiy.cn/', rel='external nofollow', title='前往云盘主页', target='_blank', one-link-mark='yes')
img.back-menu-item-icon(src='https://image.anzhiy.cn/adminuploads/1/2022/09/15/63232b7d91d22.jpg')
span.back-menu-item-text 云盘主页
a.back-menu-item(href='https://cloud.anzhiy.cn/', rel='external nofollow', title='前往安知鱼云盘', target='_blank', one-link-mark='yes')
img.back-menu-item-icon(src='https://image.anzhiy.cn/adminuploads/1/2022/04/27/6268e7d9de532.png')
span.back-menu-item-text 安知鱼云盘
.back-menu-list-group
.back-menu-list-title 项目
.back-menu-list
a.back-menu-item(href='http://blgou.net/#/main/home', title='查看德信官网', target='_blank', rel='noopener nofollow', one-link-mark='yes')
img.back-menu-item-icon.entered.exited(src='https://image.anzhiy.cn/adminuploads/1/2022/09/15/6322cd942dbd9.png')
span.back-menu-item-text 德信官网
a#site-name(href=url_for('/')) #[=config.title]
div.mask-name-container
center(id="name-container")
a(id="page-name" href="javascript:rmf.scrollToTop()") PAGE_NAME
#menus
if (theme.algolia_search.enable || theme.local_search.enable)
div.nav-button#search-button
a.site-page.social-icon.search
i.fas.fa-search.fa-fw
span=' '+_p('search.title')
if darkmode.enable && darkmode.button
div.nav-button#darkmode_navswitch
a.darkmode_switchbutton(type="button" title=_p('rightside.night_mode_title') onclick="rmf.switchDarkMode()")
i.fas.fa-adjust
div.nav-button#nav-totop
a.totopbtn
i.fas.fa-arrow-up
span#percent(onclick="btf.scrollToDest(0,500)") 0
!=partial('includes/header/menu_item', {}, {cache: true})
#toggle-menu
a.site-page
i.fas.fa-bars.fa-fw

在分类页面和archives页面添加统计图

点击下拉查看具体内容


1.安装npm(npm install hexo-butterfly-charts —save)插件

1
npm install hexo-butterfly-charts --save

2.修改 Butterfly config 配置

在您的_config.butterfly.yml中添加如下字段

1
2
3
4
5
6
7
8
9
10
11
12
#see https://www.npmjs.com/package/hexo-butterfly-charts
charts:
enable: true
postsChart:
title: 文章發佈統計
interval: 1
tagsChart:
title: Top 10 tags
interval: 1
postsCalendar_Title: 文章發佈日曆
categoriesChart_Title: 分類統計
categoriesRadar_Title: 分類雷達

3.针对分类页面进行添加

在主题目录中: .\themes\Butterfly\layout\page.pug

如果信息差不多可以直接复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
extends includes/layout.pug

block content
#page
if top_img === false
h1.page-title= page.title
case page.type
when 'tags'
include includes/page/tags.pug
when 'link'
include includes/page/flink.pug
when 'categories'
+ #categories-chart
+ #categories-radar
include includes/page/categories.pug
when 'notice'
include includes/page/notice.pug
default
include includes/page/default-page.pug
if page.comments !== false && theme.comments && theme.comments.use
- var commentsJsLoad = true
!=partial('includes/third-party/comments/index', {}, {cache: true})

4.针对archives页面进行添加

在主题目录中 .\themes\Butterfly\layout\archive.pug,

1
2
3
4
5
6
7
8
9
10
11
extends includes/layout.pug

block content
include ./includes/mixins/article-sort.pug
#archive
+ #posts-chart
+ #posts-calendar
- const archiveLength = findArchiveLength(fragment_cache)
.article-sort-title= _p('page.articles') + ' - ' + archiveLength
+articleSort(page.posts)
include includes/pagination.pug

这里写了一些比较nice的魔改教程,也参考了好多博主的教程

给博客/网站顶部加上加载进度条

点击下拉查看具体内容

这里就直接上效果比较Nice一种方式咯

这种方式适合加载比较缓慢的,能够看出效果来,会消耗用户的硬件资源,影响体验

引入css文件

在/themes/butterfly/source/css/`新建一个css文件,名字自定义,这里我就以loading-bar.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
.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: 4px;
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: .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: .3s;
top: -8px
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}

关于进度条的颜色修改主要修改如下即可

1
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);

渐变网站推荐:

Grabient

uiGradients - Beautiful colored gradients

关于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
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
/*!
* pace.js v1.2.4
* https://github.com/CodeByZach/pace/
* Licensed MIT © HubSpot, Inc.
*/
!
function() {
function o(t, e) {
return function() {
return t.apply(e, arguments)
}
}
var u, c, i, s, n, y, t, l, v, r, a, p, e, h, w, b, f, g, d, m, k, S, q, L, x, P, T, R, j, O, E, M, A, C, N, _, F, U, W, X, D, H, I, z, G, B, J = [].slice,
K = {}.hasOwnProperty,
Q = function(t, e) {
for (var n in e) K.call(e, n) && (t[n] = e[n]);
function r() {
this.constructor = t
}
return r.prototype = e.prototype,
t.prototype = new r,
t.__super__ = e.prototype,
t
},
V = [].indexOf ||
function(t) {
for (var e = 0,
n = this.length; e < n; e++) if (e in this && this[e] === t) return e;
return - 1
};
function Y() {}
for (g = {
className: "",
catchupTime: 100,
initialRate: .03,
minTime: 250,
ghostTime: 100,
maxProgressPerFrame: 20,
easeFactor: 1.25,
startOnPageLoad: !0,
restartOnPushState: !0,
restartOnRequestAfter: 500,
target: "body",
elements: {
checkInterval: 100,
selectors: ["body"]
},
eventLag: {
minSamples: 10,
sampleCount: 3,
lagThreshold: 3
},
ajax: {
trackMethods: ["GET"],
trackWebSockets: !0,
ignoreURLs: []
}
},
P = function() {
var t;
return null != (t = "undefined" != typeof performance && null !== performance && "function" == typeof performance.now ? performance.now() : void 0) ? t: +new Date
},
R = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame, f = window.cancelAnimationFrame || window.mozCancelAnimationFrame, p = function(t, e, n) {
if ("function" == typeof t.addEventListener) return t.addEventListener(e, n, !1);
var r;
"function" != typeof t["on" + e] || "object" != typeof t["on" + e].eventListeners ? (r = new s, "function" == typeof t["on" + e] && r.on(e, t["on" + e]), t["on" + e] = function(t) {
return r.trigger(e, t)
},
t["on" + e].eventListeners = r) : r = t["on" + e].eventListeners,
r.on(e, n)
},
null == R && (R = function(t) {
return setTimeout(t, 50)
},
f = function(t) {
return clearTimeout(t)
}), O = function(e) {
var n = P(),
r = function() {
var t = P() - n;
return 33 <= t ? (n = P(), e(t,
function() {
return R(r)
})) : setTimeout(r, 33 - t)
};
return r()
},
j = function() {
var t = arguments[0],
e = arguments[1],
n = 3 <= arguments.length ? J.call(arguments, 2) : [];
return "function" == typeof t[e] ? t[e].apply(t, n) : t[e]
},
d = function() {
for (var t, e, n, r = arguments[0], s = 2 <= arguments.length ? J.call(arguments, 1) : [], o = 0, i = s.length; o < i; o++) if (e = s[o]) for (t in e) K.call(e, t) && (n = e[t], null != r[t] && "object" == typeof r[t] && null != n && "object" == typeof n ? d(r[t], n) : r[t] = n);
return r
},
h = function(t) {
for (var e, n, r = e = 0,
s = 0,
o = t.length; s < o; s++) n = t[s],
r += Math.abs(n),
e++;
return r / e
},
k = function(t, e) {
var n, r;
if (null == t && (t = "options"), null == e && (e = !0), r = document.querySelector("[data-pace-" + t + "]")) {
if (n = r.getAttribute("data-pace-" + t), !e) return n;
try {
return JSON.parse(n)
} catch(t) {
return "undefined" != typeof console && null !== console ? console.error("Error parsing inline pace options", t) : void 0
}
}
},
Y.prototype.on = function(t, e, n, r) {
var s;
return null == r && (r = !1),
null == this.bindings && (this.bindings = {}),
null == (s = this.bindings)[t] && (s[t] = []),
this.bindings[t].push({
handler: e,
ctx: n,
once: r
})
},
Y.prototype.once = function(t, e, n) {
return this.on(t, e, n, !0)
},
Y.prototype.off = function(t, e) {
var n, r, s;
if (null != (null != (r = this.bindings) ? r[t] : void 0)) {
if (null == e) return delete this.bindings[t];
for (n = 0, s = []; n < this.bindings[t].length;) this.bindings[t][n].handler === e ? s.push(this.bindings[t].splice(n, 1)) : s.push(n++);
return s
}
},
Y.prototype.trigger = function() {
var t, e, n, r, s, o, i = arguments[0],
a = 2 <= arguments.length ? J.call(arguments, 1) : [];
if (null != (r = this.bindings) && r[i]) {
for (n = 0, o = []; n < this.bindings[i].length;) e = (s = this.bindings[i][n]).handler,
t = s.ctx,
s = s.once,
e.apply(null != t ? t: this, a),
s ? o.push(this.bindings[i].splice(n, 1)) : o.push(n++);
return o
}
},
B = Y, y = window.Pace || {},
window.Pace = y, d(y, B.prototype), T = y.options = d({},
g, window.paceOptions, k()), X = 0, H = (z = ["ajax", "document", "eventLag", "elements"]).length; X < H; X++) ! 0 === T[C = z[X]] && (T[C] = g[C]);
function Z() {
return Z.__super__.constructor.apply(this, arguments)
}
function $() {
this.progress = 0
}
function tt() {
this.bindings = {}
}
function et() {
var e, o = this;
et.__super__.constructor.apply(this, arguments),
e = function(r) {
var s = r.open;
return r.open = function(t, e, n) {
return A(t) && o.trigger("request", {
type: t,
url: e,
request: r
}),
s.apply(r, arguments)
}
},
window.XMLHttpRequest = function(t) {
t = new W(t);
return e(t),
t
};
try {
m(window.XMLHttpRequest, W)
} catch(t) {}
if (null != U) {
window.XDomainRequest = function() {
var t = new U;
return e(t),
t
};
try {
m(window.XDomainRequest, U)
} catch(t) {}
}
if (null != F && T.ajax.trackWebSockets) {
window.WebSocket = function(t, e) {
var n = null != e ? new F(t, e) : new F(t);
return A("socket") && o.trigger("request", {
type: "socket",
url: t,
protocols: e,
request: n
}),
n
};
try {
m(window.WebSocket, F)
} catch(t) {}
}
}
function nt() {
this.complete = o(this.complete, this);
var t = this;
this.elements = [],
S().on("request",
function() {
return t.watch.apply(t, arguments)
})
}
function rt(t) {
var e, n, r, s;
for (null == t && (t = {}), this.complete = o(this.complete, this), this.elements = [], null == t.selectors && (t.selectors = []), n = 0, r = (s = t.selectors).length; n < r; n++) e = s[n],
this.elements.push(new i(e, this.complete))
}
function st(t, e) {
this.selector = t,
this.completeCallback = e,
this.progress = 0,
this.check()
}
function ot() {
var t, e, n = this;
this.progress = null != (e = this.states[document.readyState]) ? e: 100,
t = document.onreadystatechange,
document.onreadystatechange = function() {
return null != n.states[document.readyState] && (n.progress = n.states[document.readyState]),
"function" == typeof t ? t.apply(null, arguments) : void 0
}
}
function it(t) {
this.source = t,
this.last = this.sinceLastUpdate = 0,
this.rate = T.initialRate,
this.catchup = 0,
this.progress = this.lastProgress = 0,
null != this.source && (this.progress = j(this.source, "progress"))
}
B = Error,
Q(Z, B),
n = Z,
$.prototype.getElement = function() {
var t;
if (null == this.el) {
if (! (t = document.querySelector(T.target))) throw new n;
this.el = document.createElement("div"),
this.el.className = "pace pace-active",
document.body.className = document.body.className.replace(/(pace-done )|/, "pace-running ");
var e = "" !== T.className ? " " + T.className: "";
this.el.innerHTML = '<div class="pace-progress' + e + '">\n <div class="pace-progress-inner"></div>\n</div>\n<div class="pace-activity"></div>',
null != t.firstChild ? t.insertBefore(this.el, t.firstChild) : t.appendChild(this.el)
}
return this.el
},
$.prototype.finish = function() {
var t = this.getElement();
return t.className = t.className.replace("pace-active", "pace-inactive"),
document.body.className = document.body.className.replace("pace-running ", "pace-done ")
},
$.prototype.update = function(t) {
return this.progress = t,
y.trigger("progress", t),
this.render()
},
$.prototype.destroy = function() {
try {
this.getElement().parentNode.removeChild(this.getElement())
} catch(t) {
n = t
}
return this.el = void 0
},
$.prototype.render = function() {
var t, e, n, r, s, o, i;
if (null == document.querySelector(T.target)) return ! 1;
for (t = this.getElement(), r = "translate3d(" + this.progress + "%, 0, 0)", s = 0, o = (i = ["webkitTransform", "msTransform", "transform"]).length; s < o; s++) e = i[s],
t.children[0].style[e] = r;
return (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) && (t.children[0].setAttribute("data-progress-text", (0 | this.progress) + "%"), 100 <= this.progress ? n = "99": (n = this.progress < 10 ? "0": "", n += 0 | this.progress), t.children[0].setAttribute("data-progress", "" + n)),
y.trigger("change", this.progress),
this.lastRenderedProgress = this.progress
},
$.prototype.done = function() {
return 100 <= this.progress
},
c = $,
tt.prototype.trigger = function(t, e) {
var n, r, s, o, i;
if (null != this.bindings[t]) {
for (i = [], r = 0, s = (o = this.bindings[t]).length; r < s; r++) n = o[r],
i.push(n.call(this, e));
return i
}
},
tt.prototype.on = function(t, e) {
var n;
return null == (n = this.bindings)[t] && (n[t] = []),
this.bindings[t].push(e)
},
s = tt,
W = window.XMLHttpRequest,
U = window.XDomainRequest,
F = window.WebSocket,
m = function(t, e) {
var n, r = [];
for (n in e.prototype) try {
null == t[n] && "function" != typeof e[n] ? "function" == typeof Object.defineProperty ? r.push(Object.defineProperty(t, n, {
get: function(t) {
return function() {
return e.prototype[t]
}
} (n),
configurable: !0,
enumerable: !0
})) : r.push(t[n] = e.prototype[n]) : r.push(void 0)
} catch(t) {
0
}
return r
},
L = [],
y.ignore = function() {
var t = arguments[0],
e = 2 <= arguments.length ? J.call(arguments, 1) : [];
return L.unshift("ignore"),
e = t.apply(null, e),
L.shift(),
e
},
y.track = function() {
var t = arguments[0],
e = 2 <= arguments.length ? J.call(arguments, 1) : [];
return L.unshift("track"),
e = t.apply(null, e),
L.shift(),
e
},
A = function(t) {
if (null == t && (t = "GET"), "track" === L[0]) return "force";
if (!L.length && T.ajax) {
if ("socket" === t && T.ajax.trackWebSockets) return ! 0;
if (t = t.toUpperCase(), 0 <= V.call(T.ajax.trackMethods, t)) return ! 0
}
return ! 1
},
Q(et, s),
t = et,
D = null,
M = function(t) {
for (var e, n = T.ajax.ignoreURLs,
r = 0,
s = n.length; r < s; r++) if ("string" == typeof(e = n[r])) {
if ( - 1 !== t.indexOf(e)) return ! 0
} else if (e.test(t)) return ! 0;
return ! 1
},
(S = function() {
return D = null == D ? new t: D
})().on("request",
function(t) {
var o, i = t.type,
a = t.request,
e = t.url;
if (!M(e)) return y.running || !1 === T.restartOnRequestAfter && "force" !== A(i) ? void 0 : (o = arguments, "boolean" == typeof(e = T.restartOnRequestAfter || 0) && (e = 0), setTimeout(function() {
var t, e, n, r, s = "socket" === i ? a.readyState < 1 : 0 < (s = a.readyState) && s < 4;
if (s) {
for (y.restart(), r = [], t = 0, e = (n = y.sources).length; t < e; t++) {
if ((C = n[t]) instanceof u) {
C.watch.apply(C, o);
break
}
r.push(void 0)
}
return r
}
},
e))
}),
nt.prototype.watch = function(t) {
var e = t.type,
n = t.request,
t = t.url;
if (!M(t)) return n = new("socket" === e ? r: a)(n, this.complete),
this.elements.push(n)
},
nt.prototype.complete = function(e) {
return this.elements = this.elements.filter(function(t) {
return t !== e
})
},
u = nt,
a = function(e, n) {
var t, r, s, o, i = this;
if (this.progress = 0, null != window.ProgressEvent) for (p(e, "progress",
function(t) {
return t.lengthComputable ? i.progress = 100 * t.loaded / t.total: i.progress = i.progress + (100 - i.progress) / 2
}), t = 0, r = (o = ["load", "abort", "timeout", "error"]).length; t < r; t++) p(e, o[t],
function() {
return n(i),
i.progress = 100
});
else s = e.onreadystatechange,
e.onreadystatechange = function() {
var t;
return 0 === (t = e.readyState) || 4 === t ? (n(i), i.progress = 100) : 3 === e.readyState && (i.progress = 50),
"function" == typeof s ? s.apply(null, arguments) : void 0
}
},
r = function(t, e) {
for (var n, r = this,
s = this.progress = 0,
o = (n = ["error", "open"]).length; s < o; s++) p(t, n[s],
function() {
return e(r),
r.progress = 100
})
},
rt.prototype.complete = function(e) {
return this.elements = this.elements.filter(function(t) {
return t !== e
})
},
k = rt,
st.prototype.check = function() {
var t = this;
return document.querySelector(this.selector) ? this.done() : setTimeout(function() {
return t.check()
},
T.elements.checkInterval)
},
st.prototype.done = function() {
return this.completeCallback(this),
this.completeCallback = null,
this.progress = 100
},
i = st,
ot.prototype.states = {
loading: 0,
interactive: 50,
complete: 100
},
B = ot,
Q = function() {
var e, n, r, s, o, i = this;
this.progress = 0,
o = [],
s = 0,
r = P(),
n = setInterval(function() {
var t = P() - r - 50;
return r = P(),
o.push(t),
o.length > T.eventLag.sampleCount && o.shift(),
e = h(o),
++s >= T.eventLag.minSamples && e < T.eventLag.lagThreshold ? (i.progress = 100, clearInterval(n)) : i.progress = 3 / (e + 3) * 100
},
50)
},
it.prototype.tick = function(t, e) {
return 100 <= (e = null == e ? j(this.source, "progress") : e) && (this.done = !0),
e === this.last ? this.sinceLastUpdate += t: (this.sinceLastUpdate && (this.rate = (e - this.last) / this.sinceLastUpdate), this.catchup = (e - this.progress) / T.catchupTime, this.sinceLastUpdate = 0, this.last = e),
e > this.progress && (this.progress += this.catchup * t),
e = 1 - Math.pow(this.progress / 100, T.easeFactor),
this.progress += e * this.rate * t,
this.progress = Math.min(this.lastProgress + T.maxProgressPerFrame, this.progress),
this.progress = Math.max(0, this.progress),
this.progress = Math.min(100, this.progress),
this.lastProgress = this.progress,
this.progress
},
v = it,
b = e = _ = w = E = N = null,
y.running = !1,
q = function() {
if (T.restartOnPushState) return y.restart()
},
null != window.history.pushState && (I = window.history.pushState, window.history.pushState = function() {
return q(),
I.apply(window.history, arguments)
}),
null != window.history.replaceState && (G = window.history.replaceState, window.history.replaceState = function() {
return q(),
G.apply(window.history, arguments)
}),
l = {
ajax: u,
elements: k,
document: B,
eventLag: Q
},
(x = function() {
var t, e, n, r, s, o, i, a;
for (y.sources = N = [], e = 0, r = (o = ["ajax", "elements", "document", "eventLag"]).length; e < r; e++) ! 1 !== T[t = o[e]] && N.push(new l[t](T[t]));
for (n = 0, s = (a = null != (i = T.extraSources) ? i: []).length; n < s; n++) C = a[n],
N.push(new C(T));
return y.bar = w = new c,
E = [],
_ = new v
})(),
y.stop = function() {
return y.trigger("stop"),
y.running = !1,
w.destroy(),
b = !0,
null != e && ("function" == typeof f && f(e), e = null),
x()
},
y.restart = function() {
return y.trigger("restart"),
y.stop(),
y.start()
},
y.go = function() {
var m;
return y.running = !0,
w.render(),
m = P(),
b = !1,
e = O(function(t, e) {
w.progress;
for (var n, r, s, o, i, a, u, c, l, p, h = a = 0,
f = !0,
g = u = 0,
d = N.length; u < d; g = ++u) for (C = N[g], i = null != E[g] ? E[g] : E[g] = [], s = c = 0, l = (r = null != (p = C.elements) ? p: [C]).length; c < l; s = ++c) o = r[s],
f &= (o = null != i[s] ? i[s] : i[s] = new v(o)).done,
o.done || (h++, a += o.tick(t));
return n = a / h,
w.update(_.tick(t, n)),
w.done() || f || b ? (w.update(100), y.trigger("done"), setTimeout(function() {
return w.finish(),
y.running = !1,
y.trigger("hide")
},
Math.max(T.ghostTime, Math.max(T.minTime - (P() - m), 0)))) : e()
})
},
y.start = function(t) {
d(T, t),
y.running = !0;
try {
w.render()
} catch(t) {
n = t
}
return document.querySelector(".pace") ? (y.trigger("start"), y.go()) : setTimeout(y.start, 50)
},
"function" == typeof define && define.amd ? define(function() {
return y
}) : "object" == typeof exports ? module.exports = y: T.startOnPageLoad && y.start()
}.call(this);

_config.butterfly.yml主题文件中加入

1
2
3
4
inject:
head:
- <script src="https://npm.elemecdn.com/pace-js@latest/pace.min.js"></script>
- <link rel="stylesheet" href="/css/load.css">

网站标题部分的增强版

点击下拉查看具体内容

看到洪哥他们的有一个非常高大上的动画,一直没有实现,看到博主LYXの小破站 (yisous.xyz)的教程实现了,就整了一下

引入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
#site-name::before{
opacity: 0;
background-color: var(--lyx-theme)!important;
border-radius: 8px;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
-ms-border-radius: 8px;
-o-border-radius: 8px;
transition: .3s;
-webkit-transition: .3s;
-moz-transition: .3s;
-ms-transition: .3s;
-o-transition: .3s;
position:absolute;
top:0!important;
right:0!important;
width:100%;
height:100%;
content: "\f015";
box-shadow: 0 0 5px var(--lyx-theme);
font-family: "Font Awesome 6 Free";
text-align: center;
color:white;
line-height:34px;/*如果有溢出或者垂直不居中的现象微调一下这个参数*/
font-size: 20px;/*根据个人喜好*/
}
#site-name:hover::before{
opacity: 1;
scale:1.03;
}
#site-name{
position: relative;
font-size: 22px; /*一定要把字体调大点,否则效果惨不忍睹!*/
}
:root{
--lyx-theme:#8600FF /*我的主题色*/
}

_config.butterfly.yml主题文件中加入

记得在_config.butterfly.yml引入哦

菜单栏居中

点击下拉查看具体内容

这个直接引入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
.layout{
max-width:1400px;
}
.aside-content{
max-width:312px;
}
/* @media screen and (max-width: 900px){
.card-widget:not(#card-toc){
display:none!important;
}
} */
@media screen and (max-width: 900px){
.aside-content{
max-width:none!important;
}
}
#archive,#page,#category,#tag{
width:100%;
}
.page:not(.page.home) .aside-content{
display: none;
}
@media screen and (min-width: 1300px) {
#recent-posts{
margin-top:-1rem; /*头部为空时抵消间隔,若有磁贴或日历请注释掉该行*/
align-content:flex-start;
display: flex;
flex-wrap: wrap; /*规定灵活的项目在必要的时候拆行或拆列。*/
justify-content: space-between; /*。*/
}
#recent-posts > .recent-post-item {
/*max-height:324px;*/ /*文章容器最大高度*/
margin-top: 1rem; /*最小间距*/
display: inline-block;
height:auto; /*高度自动*/
width:49%;/*文章容器容器宽度*/
}
#recent-posts > .recent-post-item .post_cover {
width: 100%; /*图片封面宽度*/
height: 200px;/*图片封面高度*/
}
#recent-posts > .recent-post-item .post_cover img.post_bg {
width: 100%;/*图片宽度*/
height: 100%;/*图片高度*/
}
#recent-posts > .recent-post-item {

-webkit-flex-direction: column; /*容器内部纵向排列*/
-ms-flex-direction: column; /*容器内部纵向排列*/
flex-direction: column; /*容器内部纵向排列*/

}
#recent-posts > .recent-post-item .left_radius {
border-radius: 8px 8px 0 0;/*圆角修改*/
}
#recent-posts > .recent-post-item .right_radius {
border-radius: 8px 8px 0 0;/*圆角修改*/
}
.recent-post-item{
height:auto !important;/*容器高度自动*/
}

.recent-post-info {

padding: 0 40px;/*容器内部文字左右间距*/
margin-top: 1em;/*容器内部文字上间距*/
width: 100%!important;/*容器宽度*/
}
#recent-posts > .recent-post-item > .recent-post-info > .article-title {
-webkit-line-clamp: 1;/*控制标题的行数*/
margin-top: 0.3rem; /*控制标题的上间距*/
margin-bottom: 0.3rem;/*控制标题的下间距*/
color: var(--text-highlight-color);
font-size: 1.2em; /*控制标题的字体大小*/
line-height: 1.4;/*控制标题的行高*/

}
#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap {
margin-bottom: 1rem;/*控制标题meta信息的底部间距*/
}
}

#nav-right{
flex:1 1 auto;
justify-content: flex-end;
margin-left: auto;
display: flex;
flex-wrap:nowrap;
}

_config.butterfly.yml主题文件中加入

记得在_config.butterfly.yml引入哦

Categories Magnet【磁贴】

点击下拉查看具体内容

由于某种原因,这个并未采用,这个请移步 Akilarの糖果屋相关教程

Categories Magnet | Akilarの糖果屋

最新文章标志

点击下拉查看具体内容

此部分参考添加最新文章标志 | Jayhrn - 分享科技与热爱生活

非修改源码方案

  • 1.新建 [BlogSource]/themes/butterfly/source/js/custom/newest_post.js 文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 旧版,本站采用
// 确保其他页面第一个不添加
if (location.pathname == '/') newPost();

// 最新文章
function newPost() {
// 获取此类名而不是获取recent-post-item是因为一些插件也会使用recent-post-item类。
// 所以获取recent-post-info可以确保每一篇都是文章。
let ls = document.querySelectorAll('.recent-post-info')
for (let i = 0; i < ls.length; i++) {
// 如果是置顶则跳过,所以如果你最新文章置顶的话就无法添加标志,只会给到置顶下面最新的文章。
// 不过一般来说置顶文章都会是早期文章,实在不行置顶之后再写一篇😂
if (ls[i].querySelector('.sticky')) continue;
let className = '';
// 封面在右则在左边添加,否则在右边
// 其实你也可以直接放在左边,我之所以这样弄是为了避免和分类图标冲突
if (ls[i].previousSibling.classList.contains('right')) className = 'newPost-left';
else className = 'newPost-right';
ls[i].innerHTML += '<span class="' + className + '">最 新</span>';
return
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 新代码,利用创建时间来判断
// 确保其他页面第一个不添加
if (location.pathname == '/') newPost();

// 最新文章
function newPost() {
let ls = document.querySelectorAll('.recent-post-info')
// 先让时间和索引值都等于第一个的
let time = new Date(ls[0].querySelector('.post-meta-date-created').getAttribute('datetime')).getTime();
let index = 0
// 遍历数组,如果有时间比time大的则替换
ls.forEach((i, num) => {
let t = new Date(i.querySelector('.post-meta-date-created').getAttribute('datetime')).getTime()
if (t > time) {
time = t;
index = num
}
})
// 单数在右,双数在左
let className = index % 2 == 0 ? 'newPost-right' : 'newPost-left'
ls[index].innerHTML += '<span class="' + className + '">最 新</span>';
// 如果你不想让其一左一右,可以注释上面的启用下面的
// ls[index].innerHTML += '<span class="newPost-left">最 新</span>';
}
  • 2.新建 [BlogSource]/themes/butterfly/source/css/custom/newest_post.css 文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.newPost-left,
.newPost-right::before {
content: "new";
width: 3rem;
height: 2rem;
border-radius: 8px;
text-align: center;
line-height: 2rem;
color: #fff;
position: absolute;
top: 8px;
left: 8px;
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
}
  • 3.引入css和js
1
2
3
4
5
6
inject:
head:
- <link rel="stylesheet" href="/css/custom_mg/newest_post.css">
bottom:
# 引入自定义js,判断最新文章[加上 data-pjax 是为了由于开启 pjax 引起切换页面后失效]
- <script defer="" src="/js/custom/newest_post.js" data-pjax=""></script>

Hexo 白昼切换

点击下拉查看具体内容
白天黑夜转换动画

看惯了Hexo Butterfly默认的黑夜/白天效果,正好看到 Jayhrnの糖衣阁大佬的黑白切换效果超级nice,所以也是第一时间换上了,下面告诉大家一下相关配置,相关文件大家也是可以在Gitee上找到的,链接我放底下了哦

(1)在themes\butterfly\layout\includes\custom\下新建一个sun_moon.pug【如果includes\下没有custom,记得自己创建哦】

主要用途:通过 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 01030.165333-30.165333z', fill='#030835', p-id='11346')

(2)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)在\themes\butterfly\source\js\custom\下新建sun_moon.js【如果js\下没有custom,记得自己创建哦】

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
11
//- global config
!=partial('includes/head/config', {}, {cache: true})

include ./head/config_site.pug
include ./head/noscript.pug
include ./custom/sun_moon.pug【添加上这句】

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

!=fragment_cache('injectHead', function(){return injectHtml(theme.inject.head)})

(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
4
inject:
head:
bottom:
- <script src="/js/custom/sun_moon.js" async></script>

下面就是老规矩,把用到的文件放到gitee上了哦,记得点img