前言

美化之前

美化的时候需要修改网站的源文件、添加样式、js之类的,需要一点基础,可以参考

在添加完js、css后,一定要记得在_config.butterfly.ymlinject里引用

1. 导航栏 nav

2. 消息弹窗Snackbar

3. 右键菜单

4. 隐藏左栏

效果图

修改效果:在一些不需要展示过多信息的界面(如:归档,分类详情,友链等等)隐藏左栏

参考链接

忘记是从哪位大佬那借鉴的了,😓

1. 修改_config.butterfly.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# aside (側邊欄)
# --------------------------------------

aside:
enable: true
hide: false
button: true
mobile: true # display on mobile
position: left # left or right
display:
archive: false
tag: false
category: false
flink: false # 友链页隐藏侧栏

2. 修改layout.pug

修改[blogRoot]\themes\butterfly\layout\includes\layout.pug

1
2
3
4
5
    - var htmlClassHideAside = theme.aside.enable && theme.aside.hide ? 'hide-aside' : ''
- page.aside = is_archive() ? theme.aside.display.archive: is_category() ? theme.aside.display.category : is_tag() ? theme.aside.display.tag : page.aside
+ - page.aside = page.type === 'link' ? theme.aside.display.flink : page.aside // - 友链页隐藏侧栏
- var hideAside = !theme.aside.enable || page.aside === false ? 'hide-aside' : ''
- var pageType = is_post() ? 'post' : 'page'

5. 页脚

效果图

参考链接

1. 添加footer.pug文件

新建 [blogRoot]\themes\butterfly\layout\includes\footer.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
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
#footer-wrap
#footer-left
.footer-title
span= config.title + ' | '
if theme.footer.owner.enable
- var now = new Date()
- var nowYear = now.getFullYear()
if theme.footer.owner.since && theme.footer.owner.since != nowYear
span.footer-copyright!= `©${theme.footer.owner.since} - ${nowYear} By ${config.author}`
else
span.footer-copyright!= `©${nowYear} By ${config.author}`
.wordcount
- let allword = totalcount(site)
span= 'June 已经写了 ' + allword + ' 字,'
if isNaN(allword)
- allword= Number(allword.replace('k', ''))
if allword< 30
span= "还在努力更新中.. 加油啦!"
else if allword< 50
span= "好像写完一本 海明威 的 《老人与海》 了啊"
else if allword< 70
span= "好像写完一本 埃克苏佩里 的 《小王子》 了啊"
else if allword< 90
span= "好像写完一本 鲁迅 的 《呐喊》 了啊"
else if allword< 100
span= "好像写完一本 林海音 的 《城南旧事》 了啊"
else if allword< 110
span= "好像写完一本 马克·吐温 的 《王子与乞丐》了! 了啊"
else if allword< 120
span= "好像写完一本 鲁迅 的 《彷徨》 了啊"
else if allword< 130
span= "好像写完一本 余华 的 《活着》 了啊"
else if allword< 140
span= "好像写完一本 曹禺 的 《雷雨》 了啊"
else if allword< 150
span= "好像写完一本 史铁生 的 《宿命的写作》 了啊"
else if allword< 160
span= "好像写完一本 伯内特 的 《秘密花园》 了啊"
else if allword< 170
span= "好像写完一本 曹禺 的 《日出》 了啊"
else if allword< 180
span= "好像写完一本 马克·吐温 的 《汤姆·索亚历险记》 了啊"
else if allword< 190
span= "好像写完一本 沈从文 的 《边城》 了啊"
else if allword< 200
span= "好像写完一本 亚米契斯 的 《爱的教育》 了啊"
else if allword< 210
span= "好像写完一本 巴金 的 《寒夜》 了啊"
else if allword< 220
span= "好像写完一本 东野圭吾 的 《解忧杂货店》 了啊"
else if allword< 230
span= "好像写完一本 莫泊桑 的 《一生》 了啊"
else if allword< 250
span= "好像写完一本 简·奥斯汀 的 《傲慢与偏见》 了啊"
else if allword< 280
span= "好像写完一本 钱钟书 的 《围城》 了啊"
else if allword< 300
span= "好像写完一本 张炜 的 《古船》 了啊"
else if allword< 310
span= "好像写完一本 茅盾 的 《子夜》 了啊"
else if allword< 320
span= "好像写完一本 阿来 的 《尘埃落定》 了啊"
else if allword< 340
span= "好像写完一本 艾米莉·勃朗特 的 《呼啸山庄》 了啊"
else if allword< 350
span= "好像写完一本 雨果 的 《巴黎圣母院》 了啊"
else if allword< 360
span= "好像写完一本 东野圭吾 的 《白夜行》 了啊"
else
span= "好像写完一本我国著名的 四大名著 了!!!"
else
span= "还在努力更新中.. 加油啦!"
#footer-right
.footer-totop
i.fas.fa-chevron-up(onclick='rmf.scrollToTop()')
.footer-info
p= '使用Hexo框架 | 基于butterfly修改'
//a(title='湘公网安备 2023003198号' href='http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=2023003198')= '湘公网安备 2023003198号'
a(title='湘ICP备2023003198号' href='https://beian.miit.gov.cn/')= '湘ICP备2023003198号'
//a(title='萌ICP备20223993号' href='https://icp.gov.moe/?keyword=20223993')= '萌ICP备20223993号'
.footer-service
a(title='腾讯云' href='https://cloud.tencent.com')
img(alt='腾讯云' src='https://img.june-pj.cn/img/2024/01/16/tencent.webp')
a(title='51LA' href='https://www.51.la')
img(alt='51LA' src='https://cdn.ichika.cc/typora/202211071552427.png!towebp')
a(title='CC BY-NC-SA 4.0' href='https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh')
img(alt='CC BY-NC-SA 4.0' src='https://img.june-pj.cn/img/2024/01/16/cc.webp')

记得将信息改成自己的

如果你没有定义rmf.scrollToTop(),可以替换为btf.scrollToDest(0, 500)

2. 添加footer.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
/* 页脚 */
.footer_custom_text a{
margin:0 5px;
}

#footer::before{
content:none;
}

#footer-wrap{
color:var(--june-white);
padding:50px 5% 35px 5%;
display:flex;
flex-wrap:wrap;
background:var(--june-theme);
position:relative;
}

#footer-wrap > div{
width:50%;
}

#footer-left{
text-align:left
}

.footer-title{
font-size:1.5rem;
font-weight:bold;
}

.footer-copyright{
font-size:1rem;
font-weight:normal;
}

#footer-wrap .footer-button {
display: flex;
margin: 15px 0;
}

#footer-wrap .footer-button > a {
font-size: 1.3rem;
margin-right:24px;
transition: 0.2s;
background: #566573;
width: 40px;
height: 40px;
display: flex;
border-radius: 50%;
color: white;
}

#footer-wrap .footer-button > a:hover{
background:var(--june-theme);
transition:0.2s;
}

#footer-wrap .footer-button > a i{
margin:auto;
line-height:42px;
}

#footer-wrap .iconfont{
font-size:1.3rem;
}

#footer-right {
text-align: right;
height: max-content;
margin-top: auto;
}

#footer-right p,#footer-right a{
color:var(--june-white);
}

.footer-totop {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
}

.footer-totop i {
font-size: 2rem;
animation: footerToTop 1.2s linear infinite;
}

.footer-info p{
font-size:14px;
margin:0;
}

.footer-info a{
margin-left:20px;
transition:0.2s;
}

.footer-info a:hover{
color:var(--june-theme-op)!important;
transition:0.2s;
}

.footer-info a:hover img{
filter: none!important;
transition:0.2s;
}

.footer-service img {
height: 20px;
filter: brightness(1000%); /* 将灰度图像提高亮度至白色 */
margin-left: 20px;
margin-top: 10px;
transition: 0.2s;
}

.footer-service img:hover {
filter: brightness(100%); /* 取消悬停时的滤镜效果 */
transition: 0.2s;
}

@keyframes footerToTop{
0%{
transform:translateY(0);
}
60% {
transform: translateY(-25%);
}
100% {
transform: translateY(0);
}
}

@media screen and (max-width:768px) {
#footer-wrap > div {
width: 100%;
text-align:center;
}

#footer-wrap .footer-button > a{
margin:0 auto;
}
}

6. 关于页面

7. 修改字体

8. 顶栏图片

效果图

参考链接

9. 友情链接页面

10. loading动画

效果

参考链接

11. 站点title

效果

参考链接

12. 侧栏aside

效果

参考链接

13. 调整页面宽度

参考链接

14. 首页双栏文章

参考链接

15. 即刻短文

16. 归档、分类、标签美化

17. 文章版权样式

18. 右下角悬浮菜单

19. 文章统计

20. 版权声明页面

21. 随机访问一篇文章

参考链接

22. 提高网站访问速度

店长的建议下,把插件都改为了源码版,更换了cdn,现在访问速度快了很多

23. 鼠标样式

新增cursors.css

1
2
3
4
5
6
7
8
9
10
/* 鼠标样式 */
body {
cursor: url(https://img.june-pj.cn/img/default.cur),
default;
}
a,
img {
cursor: url(https://img.june-pj.cn/img/pointer.cur),
default;
}

24. 足迹页

效果图

25. 持久化url

我使用的hexo-abbrlink插件

26. SEO搜索引擎收录

27. 卡片边框

修改[blogRoot]\themes\butterfly\source\css\_global\function.stylcardHover部分

1
2
3
4
5
6
7
8
9
10
11
// card hover
.cardHover
border-radius: 8px
background: var(--card-bg)
box-shadow: var(--card-box-shadow)
transition: all .3s
+ border: 1px solid transparent

&:hover
box-shadow: var(--card-hover-box-shadow)
+ border: 1px solid var(--june-border)
小贴士

原本我只在hover的时候加了个border,但是每次鼠标滑过的时候,页面布局都会变动,于是我这只小趴菜就去问ChatGPT

在你的CSS代码中,当鼠标悬停在卡片上时,通过添加border: 1px solid var(--june-border);属性,你引入了一个1像素宽度的边框。这个边框的添加会改变卡片的尺寸,因为边框会占用一定的空间。

这种改变可能会导致卡片的宽度增加,从而导致卡片中的文字发生换行,因为它们现在必须适应较小的可用宽度。如果在未悬停时没有边框,鼠标悬停时添加了边框,这种尺寸变化可能会导致文字重新布局,导致换行。

于是才解决😓

28. 标签外挂

原本采用的是插件版,但是因为cdn访问过慢,现已改为源码版,并修改了cdn

采用的店长的Tag Plugins Plus,但是引用链接的样式我不是很喜欢,于是找了洪哥的方案,修修改改。

下面粘出我的样式

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
#article-container .tag-Link {
background: var(--june-secondbg);
border-radius: 12px!important;
display: flex;
border: var(--style-border);
flex-direction: column;
padding: 0.5rem 1rem;
border-width: 1px!important;
margin-top: 1rem;
text-decoration: none!important;
color: var(--june-fontcolor);
margin-bottom:10px
}
#article-container .tag-Link:hover {
border-color: var(--june-theme);
background-color: var(--june-theme);
--gcolor: white!important;
box-shadow: 0 0 5px var(--june-theme);
}

#article-container .tag-Link .tag-link-tips {
border-bottom: var(--style-border);
padding-bottom: 4px;
font-size: 0.6rem;
color: var(--june-gray);
font-weight: normal;
}

#article-container .tag-Link:hover .tag-link-tips {
color: var(--june-white);
}

#article-container .tag-Link .tag-link-bottom {
display: flex;
margin-top: 0.5rem;
align-items: center;
justify-content: space-around;
}

#article-container .tag-Link .tag-link-bottom .tag-link-left {
width: 60px;
min-width: 60px;
height: 60px;
background-size: cover;
}

#article-container .tag-Link .tag-link-bottom .tag-link-right {
margin-left: 1rem;
}

#article-container .tag-Link .tag-link-bottom .tag-link-right .tag-link-title {
font-size: 1rem;
line-height: 1.2;
}

#article-container .tag-Link .tag-link-bottom .tag-link-right .tag-link-sitename {
font-size: 0.7rem;
color: var(--june-gray);
font-weight: normal;
margin-top: 4px;
}

#article-container .tag-Link:hover .tag-link-bottom .tag-link-right .tag-link-sitename {
color: var(--june-white);
}

#article-container .tag-Link .tag-link-bottom i {
margin-left: auto;
}

.tag-link-title{
color:var(--gcolor);
}

folding折叠栏样式失效,可以执行npm install hexo-butterfly-tag-plugins-plus@1.0.5 --save,也可能是cdn没加载出来,多刷新几次或者更换源码版即可

他的样式我也按照安知鱼大佬的调整了一下

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
/* 折叠栏样式 */
details.folding-tag[open] {
border-radius: 15px !important;
border-color: var(--june-main) !important;
border: 1px solid var(--june-main) !important;
}

li details.folding-tag {
border-radius: 8px;
}

li details.folding-tag summary {
border-radius: 8px;
}

details.folding-tag {
transition: border 0s ease !important;
border: none !important;
}

details.folding-tag[open] > summary {
color: var(--june-white) !important;
background: var(--june-main) !important;
border: 1px solid var(--june-main) !important;
border-top: none !important;
border-left: none !important;
border-right: none !important;
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
details.folding-tag > summary {
border: var(--style-border) !important;
background: var(--june-card-bg);
border-radius: 14px !important;
box-shadow: var(--june-shadow-border);
color: var(--font-color) !important;
user-select: none;
}
details.folding-tag > summary::marker {
color: var(--june-main);
font-size: 16px;
}
details.folding-tag > summary::before {
content: " ";
margin-right: 2px;
}
details.folding-tag[open] > div.content {
border-radius: 0 0 16px 16px;
}
details.folding-tag summary:hover::marker {
color: var(--june-white);
}
details.folding-tag[open] > summary::marker {
color: var(--june-white);
}
details.folding-tag summary:hover {
cursor: pointer;
background: var(--june-main) !important;
color: var(--june-white) !important;
transition: 0.3s;
box-shadow: var(--june-shadow-main);
}
details .content > *:nth-child(1) {
margin-top: 0 !important;
}

.flink details.folding-tag[open] > div.content {
padding: 20px;
margin: 0px;
margin-top: 0;
}

29. Twikoo评论

我采用的是Vercel部署,以Mongodb作为数据库。跟着视频教程一步步做就可以。

1. 邮件回复样式

2. 评论输入提醒

3. 测试正常,评论时收不到邮件

4. 评论区样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.tk-extras {
padding-bottom: 15px;
border-bottom: 2px dashed var(--hr-border)
}

.tk-extra {
border: var(--style-border);
padding: 4px 6px 4px 6px;
border-radius: 8px;
margin-right: 4px!important
}

.tk-expand {
margin-top: 16px;
background-color: var(--june-secondbg);
color: var(--june-fontcolor);
border-radius: 8px;
border: var(--style-border);
}

.tk-expand:hover {
background-color: var(--june)!important;
color: var(--june-white)
}

5. 表情包配置

6. 表情包放大预览

7. 评论数据备份

小插曲

我在跟着教程做的时候出了点小问题,workflow的时候爬不到数据,一看是403

action日志报错

然后我看日志,以为是没读到secrets的值,拉到本地后,给参能运行。折腾了好久,想看Action读没读到,结果怎么打印都是*,最后还是打印长度才确定没问题。

后面我一想,本地没问题,Action有问题,会不会是被Vercel搭的Twikoo评论给墙了(因为我挂了cf),于是把cfdns一关,就能访问了

可以不用关dns,把安全性的自动程序关掉就行(感谢群里的佬教我)

cf关掉安全性自动程序

30. FriendCircle朋友圈

31. 首页首个文章添加class

32. 那年今日(历史上的今天)

33. 本站运行时间

34. 轮播图Swiper

35. 分类磁贴(简略版)

样式调整(自用)

因为我首页双栏是直接调整样式的,所以挂载在.recent-posts里元素的样式可能有点小问题,所以稍微调整了一下

修改temple_html字段,新增样式margin-top: 20px;

1
temple_html: '<div class="recent-post-item" style="width: 100%; height: auto; margin-top: 20px;"><div id="catalog_magnet">${temple_html_item}</div></div>'
监视器(感觉效率不高,没用)

ChatGPT的帮助下,实现了,但是感觉会比较慢,就没用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 监视器回调函数
var mutationCallback = function(mutationsList, observer) {
for(var mutation of mutationsList) {
if (mutation.type === 'childList') {
var parent = document.querySelectorAll('.recent-post-item > #catalog_magnet')[0];
if (parent) {
parent.parentNode.classList.add('catalog_magnet_style');
observer.disconnect(); // 一旦找到目标元素,停止监视
}
}
}
};

// 配置监视器
var observer = new MutationObserver(mutationCallback);

// 配置监视器以监视根节点
observer.observe(document.body, {
childList: true, // 子节点的变动
subtree: true // 包括后代节点
});
旧版调整方案(已弃用)

之前的做法是找到父元素class为recent-post-item且子元素id为catalog_magnet,然后对其父元素添加样式catalog_magnet_style,但是这样只会在加载页面时生效,通过a标签跳转到根路径时不生效,不知道啥问题,我debugger调试的时候明明加上样式了的😭

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
// 定义一个函数来执行你的 JavaScript 代码
function executeCodeOnRootPath() {
var parent = document.querySelectorAll('.recent-post-item > #catalog_magnet')[0];
if (parent) {
parent.parentNode.classList.add('catalog_magnet_style');
}
}

// 检查当前页面路径是否为根路径
function checkRootPath() {
if (window.location.pathname === '/') {
executeCodeOnRootPath();
}
}

// 页面加载完成时检查一次路径
window.onload = function() {
checkRootPath();
};

// 监听所有 <a> 标签的点击事件
document.addEventListener('click', function(event) {
// 获取点击的元素
var target = event.target;

// 检查点击的元素是否为 <a> 标签
if (target.tagName === 'A') {
// 获取链接的目标路径
var href = target.getAttribute('href');
if (href === '/') {
// 如果目标路径为根路径,则执行你的 JavaScript 代码
executeCodeOnRootPath();
}
}
});

36. TianliGPT

字段配置:let tianliGPT_Title = "文章摘要"; let tianliGPT_Name="June";

甜梨酱的gpt

37. Toc目录卡片

可能我的版本有问题,_config.butterfly.yml里的nav可以直接配置

固定Toc目录卡片

在文章页面,滑动滚轮时Toc会随着一起上下移动,参考鹊楠佬的意见,稍微修改了一下,下面两种任选其一即可

1
2
3
4
5
@media screen and (min-width: 900px) {
#aside-content .sticky_layout {
top: 70px !important;
}
}

修改[blogRoot]\butterfly\source\css\_layout\aside.styl,大概在第82行左右

1
2
3
4
5
6
7
8
9
  ...
.sticky_layout
+minWidth900()
position: sticky
position: -webkit-sticky
- top: 20px
+ top: 70px
transition: top .3s
...
Toc目录卡片点击后文章定位调整

点击目录时,如果点击的是当前位置之前的目录,文章定位没被遮挡;但如果点击当前位置之后的目录,文章就会被导航栏遮挡

修改[blogRoot]\butterfly\source\js\utils.js,找到函数scrollToDest,大概在第123行左右

1
2
3
4
5
6
7
8
9
10
11
12
  scrollToDest: (pos, time = 500) => {
const currentPos = window.pageYOffset
- if (currentPos > pos) pos = pos - 70
+ pos = pos - 70

if ('scrollBehavior' in document.documentElement.style) {
window.scrollTo({
top: pos,
behavior: 'smooth'
})
return
}

38. 热评弹幕

39. 和风天气卡片

该插件在2024年5月1日停止服务

用了蛮久了,才发现没写进来,下面是插件地址,直接创建插件就行,其他的看佬的教程

样式调整

适配夜晚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#he-plugin-standard {
width: 100% !important;
margin-bottom: 20px !important;
}

.wv-n-h-now-aqi-item {
display: none;
}

.wv-n-h-now-tmp > span, .wv-n-h-now-txt > span, .wv-n-h-now-rain > span[data-v-6ffbc261], .wv-lt-location > span, .wv-lt-location > a, .wv-lt-refresh a, .wv-f-forecast-date > a, .wv-f-forecast-tmp > a {
color: var(--font-color) !important;
font-family: 'HYTMR', serif !important;
font-size: 14px
}

40. 移动端侧边栏悬浮窗

样式调整

微调了一下店长的样式fixed_card_widget.styl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// 垂直居中卡片样式(排除toc目录卡片)
.fixed-card-widget
&:not(#card-toc)
visibility visible!important
display block!important
position fixed!important
bottom 0
left 0
top 0
right 0
margin auto
margin-bottom auto!important
margin-top auto!important
max-width 300px
max-height 85%
width auto
height fit-content
overflow-y: scroll
z-index 999
animation rotateX 0.5s ease
animation-fill-mode forwards
&::-webkit-scrollbar
width: 0
// 针对说说卡片做样式兼容适配
.card-shuo
&.fixed-card-widget
#artitalk_main
max-height 460px
overflow scroll
&::-webkit-scrollbar
display: none
#operare_artitalk
.c2
z-index 1000
// 针对标签卡片做样式兼容适配
.card-tags
&.fixed-card-widget
.card-tag-cloud
max-height 460px
overflow scroll
&::-webkit-scrollbar
display: none
// 控制手机端可见
@media screen and (max-width: 768px)
div#fixedcard-dashboard
display flex!important
// 侧栏悬浮按钮样式
div#fixedcard-dashboard
position fixed
top 150px
width fit-content
height 40px
opacity 0.3
transition all 0.5s
display none
background rgba(255,255,255,0.9)
padding 5px 10px
border-top-right-radius 20px
border-bottom-right-radius 20px
z-index 1000
&:hover
opacity 1
button
&.fixedcard-activebtn
width 30px
opacity 1
pointer-events all
// 按钮样式
button
&.fixedcard-activebtn
width 0px
height 30px
transition all .5s
display flex
opacity 0
align-items center
justify-content space-around
pointer-events none
color #757273
// 悬浮按钮头像
.fixedcard-user-avatar
display inline-block
img
&.fixedcard-user-avatar-img
width 30px
height 30px
border-radius 50%
// 悬浮按钮夜间模式适配
[data-theme="dark"]
div#fixedcard-dashboard
background rgba(55,55,55,0.9)
button
&.fixedcard-activebtn
color #bcbdbd

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


[data-theme="dark"]
div#quit-box
background rgba(147, 146, 128, 0.3)

小Bug

因为我只有首页和文章页有侧边栏,所以其他页面点击的时候没有这些卡片,打不开,因此我小调了一下fixed_card_widget.pug

直接粘贴替换就行

1
2
3
4
5
6
7
8
9
10
11
12
if is_post() || is_home()
#fixedcard-dashboard
if is_post()
each poitem in theme.fixed_card_widget.post
button.fixedcard-activebtn(type="button" title=poitem.title onclick=`FixedCardWidget("` + poitem.type + `","` + poitem.name + `","` + poitem.index + `")`)
i(class=poitem.icon)
else
each paitem in theme.fixed_card_widget.page
button.fixedcard-activebtn(type="button" title=paitem.title onclick=`FixedCardWidget("` + paitem.type + `","` + paitem.name + `","` + paitem.index + `")`)
i(class=paitem.icon)
.fixedcard-user-avatar.fixedcard-activebtn(onclick="RemoveFixedCardWidget()")
img.fixedcard-user-avatar-img(src=url_for(theme.avatar.img) title=config.author)

41. 来访者信息

亦小封佬的js可以加上这一句document.addEventListener('DOMContentLoaded', welcometxmap);,这样刷新的时候就能加载出来了

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
// 全局变量定义
var ipLoacation;

// 获取来访者信息
function welcometxmap() {
// 请求数据
ipLoacation = window.saveToLocal.get('ipLocation');
if (ipLoacation) {
// 使用 ipLocation
showWelcome();
} else {
// 数据已过期或不存在
var script = document.createElement('script');
var url = `https://apis.map.qq.com/ws/location/v1/ip?key=${txkey}&output=jsonp`;
script.src = url;
window.QQmap = function (data) {
ipLoacation = data;
// 将数据保存到 localStorage,过期时间设置为 1 天
window.saveToLocal.set('ipLocation', ipLoacation, 1);
document.body.removeChild(script);
delete window.QQmap;
// 获取到数据后立即显示欢迎信息
showWelcome();
};
document.body.appendChild(script);
}
}

function getDistance(e1, n1, e2, n2) {
const R = 6371;
const { sin, cos, asin, PI, hypot } = Math;
let getPoint = (e, n) => {
e *= PI / 180;
n *= PI / 180;
return { x: cos(n) * cos(e), y: cos(n) * sin(e), z: sin(n) };
};

let a = getPoint(e1, n1);
let b = getPoint(e2, n2);
let c = hypot(a.x - b.x, a.y - b.y, a.z - b.z);
let r = asin(c / 2) * 2 * R;
return Math.round(r);
}

function showWelcome() {
if (!ipLoacation) return; // 确保 ipLoacation 存在

let dist = getDistance(longitude, Latitude, ipLoacation.result.location.lng, ipLoacation.result.location.lat);
let pos = ipLoacation.result.ad_info.nation;
let ip;
let posdesc;

// 根据国家、省份、城市信息自定义欢迎语
switch (ipLoacation.result.ad_info.nation) {
case "日本":
posdesc = "よろしく,一起去看樱花吗";
break;
case "美国":
posdesc = "Let us live in peace!";
break;
case "英国":
posdesc = "想同你一起夜乘伦敦眼";
break;
case "俄罗斯":
posdesc = "Высушите эту бутылку водки!";
break;
case "法国":
posdesc = "C'est La Vie";
break;
case "德国":
posdesc = "Die Zeit verging im Fluge.";
break;
case "澳大利亚":
posdesc = "一起去大堡礁吧!";
break;
case "加拿大":
posdesc = "拾起一片枫叶赠予你";
break;
case "中国":
pos = ipLoacation.result.ad_info.province + " " + ipLoacation.result.ad_info.city; // + " " + ipLoacation.result.ad_info.district;
ip = ipLoacation.result.ip;
switch (ipLoacation.result.ad_info.province) {
case "北京市":
posdesc = "北——京——欢迎你~~~";
break;
case "天津市":
posdesc = "讲段相声吧";
break;
case "河北省":
posdesc = "山势巍巍成壁垒,天下雄关铁马金戈由此向,无限江山";
break;
case "山西省":
posdesc = "展开坐具长三尺,已占山河五百余";
break;
case "内蒙古自治区":
switch (ipLoacation.result.ad_info.city) {
case "通辽市":
posdesc = "可汗宇宙中心";
break;
default:
posdesc = "天苍苍,野茫茫,风吹草低见牛羊";
break;
}
break;
case "辽宁省":
posdesc = "我想吃烤鸡架!";
break;
case "吉林省":
posdesc = "状元阁就是东北烧烤之王";
break;
case "黑龙江省":
posdesc = "很喜欢哈尔滨大剧院";
break;
case "上海市":
posdesc = "众所周知,中国只有两个城市";
break;
case "江苏省":
switch (ipLoacation.result.ad_info.city) {
case "南京市":
posdesc = "这是我挺想去的城市啦";
break;
case "苏州市":
posdesc = "上有天堂,下有苏杭";
break;
case "无锡市":
posdesc = "无锡太美,无锡太美";
break;
default:
posdesc = "散装是必须要散装的";
break;
}
break;
case "浙江省":
posdesc = "东风渐绿西湖柳,雁已还人未南归";
break;
case "河南省":
switch (ipLoacation.result.ad_info.city) {
case "郑州市":
posdesc = "豫州之域,天地之中";
break;
case "南阳市":
posdesc = "臣本布衣,躬耕于南阳此南阳非彼南阳!";
break;
case "驻马店市":
posdesc = "峰峰有奇石,石石挟仙气嵖岈山的花很美哦!";
break;
case "开封市":
posdesc = "刚正不阿包青天";
break;
case "洛阳市":
posdesc = "洛阳牡丹甲天下";
break;
default:
posdesc = "可否带我品尝河南烩面啦?";
break;
}
break;
case "安徽省":
posdesc = "蚌埠住了,芜湖起飞";
break;
case "福建省":
posdesc = "井邑白云间,岩城远带山";
break;
case "江西省":
posdesc = "落霞与孤鹜齐飞,秋水共长天一色";
break;
case "山东省":
posdesc = "遥望齐州九点烟,一泓海水杯中泻";
break;
case "湖北省":
switch (ipLoacation.result.ad_info.city) {
case "黄冈市":
posdesc = "红安将军县!辈出将才!";
break;
default:
posdesc = "来碗热干面~";
break;
}
break;
case "湖南省":
switch (ipLoacation.result.ad_info.city) {
case "衡阳市":
posdesc = "老乡见老乡,两眼泪汪汪!";
break;
default:
posdesc = "74751,长沙斯塔克";
break;
}
break;
case "广东省":
switch (ipLoacation.result.ad_info.city) {
case "广州市":
posdesc = "看小蛮腰,喝早茶了嘛~";
break;
case "深圳市":
switch (ipLoacation.result.ad_info.district) {
case "南山区":
posdesc = "好巧!博主也在南山区生活喔~";
break;
default:
posdesc = "今天你996了嘛~";
break;
}
break;
case "阳江市":
posdesc = "阳春合水!博主家乡~ 欢迎来玩~";
break;
default:
posdesc = "来两斤福建人~";
break;
}
break;
case "广西壮族自治区":
posdesc = "桂林山水甲天下";
break;
case "海南省":
posdesc = "朝观日出逐白浪,夕看云起收霞光";
break;
case "四川省":
posdesc = "康康川妹子";
break;
case "贵州省":
posdesc = "茅台,学生,再塞200";
break;
case "云南省":
posdesc = "玉龙飞舞云缠绕,万仞冰川直耸天";
break;
case "西藏自治区":
posdesc = "躺在茫茫草原上,仰望蓝天";
break;
case "陕西省":
posdesc = "来份臊子面加馍";
break;
case "甘肃省":
posdesc = "羌笛何须怨杨柳,春风不度玉门关";
break;
case "青海省":
posdesc = "牛肉干和老酸奶都好好吃";
break;
case "宁夏回族自治区":
posdesc = "大漠孤烟直,长河落日圆";
break;
case "新疆维吾尔自治区":
posdesc = "驼铃古道丝绸路,胡马犹闻唐汉风";
break;
case "台湾省":
posdesc = "我在这头,大陆在那头";
break;
case "香港特别行政区":
posdesc = "永定贼有残留地鬼嚎,迎击光非岁玉";
break;
case "澳门特别行政区":
posdesc = "性感荷官,在线发牌";
break;
default:
posdesc = "带我去你的城市逛逛吧!";
break;
}
break;
default:
posdesc = "带我去你的国家逛逛吧";
break;
}

// 根据本地时间切换欢迎语
let timeChange;
let date = new Date();
if (date.getHours() >= 5 && date.getHours() < 11) timeChange = "<span class='welcome-time'>🌤️ 早上好,一日之计在于晨</span>";
else if (date.getHours() >= 11 && date.getHours() < 13) timeChange = "<span class='welcome-time'>☀️ 中午好,记得午休喔~</span>";
else if (date.getHours() >= 13 && date.getHours() < 17) timeChange = "<span class='welcome-time'>🕞 下午好,饮茶先啦!</span>";
else if (date.getHours() >= 17 && date.getHours() < 19) timeChange = "<span class='welcome-time'>🚶‍♂️ 即将下班,记得按时吃饭~</span>";
else if (date.getHours() >= 19 && date.getHours() < 24) timeChange = "<span class='welcome-time'>🌙 晚上好,夜生活嗨起来!</span>";
else timeChange = "<span class='welcome-time'>夜深了,早点休息,少熬夜</span>";

try {
// 自定义文本和需要放的位置
document.getElementById("welcome-info").innerHTML =
`<span>欢迎来自 <b>${pos}</b> 的小伙伴</span><br>
${timeChange}<br>
<span class="welcome-message">${posdesc}</span><br>
当前位置距<b> June </b>约 <b>${dist}</b> 公里!<br>
<span>IP地址为:<b>${ip}</b></span>`;
} catch (err) {
console.log("无法获取#welcome-info元素", err);
}
}

// 在页面加载时调用welcometxmap
document.addEventListener('DOMContentLoaded', welcometxmap);

42. RSS订阅

43. 美化文章底部分享打赏按钮