惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
NISL@THU
NISL@THU
E
Exploit-DB.com RSS Feed
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
K
Kaspersky official blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
S
Schneier on Security
G
GRAHAM CLULEY
The Hacker News
The Hacker News
T
Threat Research - Cisco Blogs
Scott Helme
Scott Helme
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Cyberwarzone
Cyberwarzone
C
CERT Recently Published Vulnerability Notes
T
Tor Project blog
AWS News Blog
AWS News Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
爱范儿
爱范儿
P
Privacy International News Feed
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
S
Securelist
G
Google Developers Blog
The Last Watchdog
The Last Watchdog
Google Online Security Blog
Google Online Security Blog
美团技术团队
F
Fortinet All Blogs
小众软件
小众软件
Recorded Future
Recorded Future
V
Visual Studio Blog
B
Blog RSS Feed
H
Help Net Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
Martin Fowler
Martin Fowler
Latest news
Latest news
Spread Privacy
Spread Privacy
H
Heimdal Security Blog

爱吃肉的猫

那就,再相逢 Butterfly的魔改教程:最新评论页 离歌不夜天 前端分享 - 滑动阻尼效果 Butterfly的魔改教程:右键菜单 音乐分享 - doi微醺氛围 Butterfly的魔改教程:动态相册页 近况记事 - 11 微信公众号:Ai大模型让回复更具智能化 近况记事 - 10 PWA:让你的网站变成桌面应用APP Healthy Love Butterfly的魔改教程:关于本站 近况记事 - 9 Butterfly的魔改教程:待办清单 TrollStore - 不掉签助手 近况记事 - 8 Twikoo评论回复邮件模版 过一个很特别的七夕 The Young Boy and the Sea Butterfly的魔改教程:文章订阅页 思考题目:混乱是阶梯 近况记事 - 7 Butterfly的魔改教程:即刻短文页 Butterfly的魔改教程:loading加载动画 差旅游记 再见,不惑之年:二十又一 近况记事 - 6 Butterfly的魔改教程:自定页数跳转 堆友AI作图:3D资源设计平台,堆出你的未来 【QD-Today】自建私有自动签到服务 Long time no see Butterfly的魔改教程:聊天记录页 Butterfly的魔改教程:个性定位信息 近况记事 - 5 Butterfly的魔改教程:好物推荐页 CDN加速 二刷《想见你》 网络言论不是法外之地 近况记事 - 4 深夜训斥 近况记事 - 3 近况记事 - 2 日常打理的那些事 Butterfly的魔改教程:随机阅读一篇文章 随笔 · 封 布柒糖FM项目进展报告 清明路雨纷纷 TA - 仲夏夜的荒原 重构记录 - 4 近况记事 Butterfly的魔改教程:评论弹窗 2021款 Model Y 近两年用车总结 重构记录 - 3 百日祭 避风的港湾 Emoji表情大全 iCat-APP 开源记录 Butterfly的调整教程:文章外挂标签美化 iOS修改 - 万铲铲的致富之路 Markdown 基础教程 从你的全世界路过 小米摄像头!避!雷! VuePress 搭建教程 Hexo跳过指定文件渲染 百度贴吧每日自动签到 重构记录 - 1 GitHub Desktop提交报错 快速批量处理重命名 Git连接仓库常用命令 Ubuntu处理deb命令 掘金自动签到并挖矿 一个简洁的橙色调个人简介 我的猫以前也是流浪猫 布柒糖FM 最新指北 初学写个了油猴脚本 幽灵404页面 PC游戏 · 植物大战僵尸 语言包 · 越狱篇 砸壳多开 · 越狱篇 HuiRan Cursors 手动关闭Win10自动更新 iPhone XR 完美越狱 成功实例 三年的跌撞 关于《小橘妈妈》 Hexo 博客添加RSS插件 Butterfly的魔改教程:导航栏魔改美化
魔改前置教程:添加自定义css和js文件
亦小封 · 2021-10-22 · via 爱吃肉的猫

新手魔改博客前,最好是将自己的博客配置完,认真阅读过Butterfly官方文档,使用两三个月过后,再来逐步了解魔改的过程。这样就会避免大多数的上手难度。

其次,在你进行魔改前,必要时最好提前备份一遍你的源代码,以免造成不必要的麻烦。
譬如:效果不理想,没达到预期;魔改出问题,不小心改错了等等。

文件位置辨别

在本站的教程内,会写有[博客根目录][主题目录]两种。

  • 博客根目录:指你本地的博客项目文件夹,也就是你 clone 的项目文件夹。

  • 主题目录:指你butterfly主题文件夹,git安装或npm安装的主题文件夹。

如果你实在找不到你的主题目录,请移步: Butterfly官方文档 - 安装

添加自定义文件

魔改或美化都离不开添加自定义css和js文件,而这些的文件位置和使用是必不可少的。

一般情况下,推荐在博客根目录source文件夹内存放你自己的css和js文件。至于主题目录内的source文件,由于更新后会被覆盖掉,所以不建议。

  • 新建[博客根目录]/source/js/meuicat.js文件。

  • 新建[博客根目录]/source/css/meuicat.css文件。

  • _config.butterfly.yml主题配置文件中inject下的headbottom分别引入meuicat.css以及meuicat.js

1
2
3
4
5
6
7
inject:
head:

- <link rel="stylesheet" href="/css/meuicat.css">
bottom:

- <script src="/js/meuicat.js"></script>

如果你实在找不到你的主题配置文件,请移步: Butterfly官方文档 - 升级建议

魔改或美化教程里有大量CSS变量代码,例如:color: var(–icat-theme) 等等。
所以当你首次使用本站魔改教程前,需要在你的css样式文件中,添加以下代码:

  • 创建[主题目录]/source/css/_global/meuicat.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
:root
--icat-000 0,0,0
--icat-010 255,255,255
--icat-020 60,60,67
--icat-black-op rgbas('var(--icat-000)', .15)
--icat-gray-op #9999992b
--icat-white rgbas('var(--icat-010)', 1)
--icat-white-op rgbas('var(--icat-010)', .15)
--icat-green #3e9f50
--icat-yellow #ffc93e
--icat-red #ff3842
--icat-purple #7a60d2
--icat-none rgbas('var(--icat-000)', 0)
--icat-border-main 1px solid var(--icat-theme)
--icat-border-always 1px solid var(--icat-card-border)
--icat-border-none 1px solid var(--icat-none)
--icat-border-dashed 1px dashed var(--icat-card-border)
--icat-shadow 0 8px 16px -4px

[data-theme='light']
--icat-theme rgbas('var(--icat-blue)', 1)
--icat-theme-op rgbas('var(--icat-blue)', .14)
--icat-theme-deep rgbas('var(--icat-blue)', .42)
--icat-blue 66,90,239
--icat-pink #d80020
--icat-fontcolor #363636
--icat-background #f7f9fe
--icat-card-bg rgbas('var(--icat-010)', 1)
--icat-card-overlap rgbas('var(--icat-010)', 1)
--icat-card-border #e3e8f7
--icat-shadow-border var(--icat-shadow) #2c2d300c
--icat-shadow-main var(--icat-shadow) var(--icat-theme-op)
--icat-mask rgbas('var(--icat-010)', .85)
--icat-mask-op rgbas('var(--icat-010)', .6)
--icat-secondbg #f7f7f9
--icat-secondtext rgbas('var(--icat-020)', .8)
--icat-sparent var(--icat-white-op)

if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark'
[data-theme='dark']
--icat-theme rgbas('var(--icat-orange)', 1)
--icat-theme-op rgbas('var(--icat-orange)', .14)
--icat-theme-deep rgbas('var(--icat-orange)', .42)
--icat-orange 255,149,62
--icat-pink #d44040
--icat-fontcolor #F7F7FA
--icat-background #18171d
--icat-card-bg #1b1c20
--icat-card-overlap #161823
--icat-card-border #3d3d3f
--icat-shadow-border var(--icat-shadow) rgbas('var(--icat-000)', .314)
--icat-shadow-main var(--icat-shadow) var(--icat-theme-op)
--icat-mask rgbas('var(--icat-000)', .85)
--icat-mask-op rgbas('var(--icat-000)', .6)
--icat-secondbg #21232a
--icat-secondtext #a1a2b8
--icat-sparent var(--icat-black-op)

版本迭代后,可能会有些许变化,可自行通过F12获取。

icon 图标

本站的魔改教程中,有部分包含icon图标。你可以选择引用我的图标库直接使用,又或者将其改成你自己的图标。

  • _config.butterfly.yml主题配置文件中inject下的head引入iconfont.css
1
2
3
4
5
6
inject:
head:

- <link rel="stylesheet" href="/css/meuicat.css">

- <link rel="stylesheet" href="https://cdn2.codesign.qq.com/icons/xnjPoz51lMm6KZL/latest/iconfont.css" media="print" onload="this.media='all'">

通用样式

为避免重复样式冗余,可自行选择对应的通用样式。小节内容会随着本站魔改教程系列的更新而更新。

cardHovers

  • 打开[主题目录]/source/css/_global/meuicat.styl样式文件,并新增以下内容。
1
2
3
4
5
6
7
8
9
10
.cardHovers
background: var(--icat-card-bg)
border-radius 8px
border var(--icat-border-always)
box-shadow: var(--icat-shadow-border)
transition: all .3s

&:hover
border var(--icat-border-main)
box-shadow: var(--icat-shadow-main)

aplayer

  • 创建[主题目录]/source/css/_layout/aplayer.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
.aplayer.aplayer-withlrc
background var(--icat-secondbg)
text-align center
border var(--icat-border-always)
border-radius 8px
box-shadow initial

.aplayer-pic
.aplayer-button path
transition all .1s ease

&:hover
.aplayer-button,
.aplayer-button path
fill var(--icat-theme)
border-color var(--icat-theme)

.aplayer-lrc
&:after,
&:before
display none

p.aplayer-lrc-current
color var(--icat-theme)

.aplayer-info
.aplayer-controller
.aplayer-bar-wrap .aplayer-bar
background var(--icat-card-border)
height 8px
border-radius 99px
transition .3s
overflow hidden

.aplayer-loaded
height 100%
background var(--icat-theme-op)

.aplayer-played
height 100%
border-radius 99px

.aplayer-thumb
display none

.aplayer-time
position initial

.aplayer-icon:hover path
fill var(--icat-theme)

.aplayer-music .aplayer-title
font-weight 700

通用函数

本站魔改教程中,有部分会使用到相同的辅助函数,为了减少重复代码,重复使用两次以上的通用辅助函数,将会放在本小节内。

小节内容会随着本站魔改教程系列的更新而更新。通用函数将添加在[博客根目录]/source/js/meuicat.js文件中,即可。
唯一需要注意的是,同一个常量函数,只需声明一次。

changeTime

所需范围:Butterfly的魔改教程:最新评论页、Butterfly的魔改教程:即刻短文页

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
const changeTime = (time, more = false) => {
const currentDate = new Date()

const formatTimestamp = (date) => {
const d = new Date(date)
const pad = (num) => String(num).padStart(2, '0')
return `${pad(d.getFullYear())}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ` + `${pad(d.getHours())}:${pad(d.getMinutes())}`
}

const calculateDiff = (date1, date2, unit) => {
const units = { day: 24 * 60 * 60 * 1000, hour: 60 * 60 * 1000 }
return Math.floor(Math.abs(date1 - date2) / units[unit])
}

const describeTime = (datetime) => {
const timeObj = new Date(datetime)
const diffDays = calculateDiff(timeObj, currentDate, 'day')
const diffHours = calculateDiff(timeObj, currentDate, 'hour')

if (diffHours < 1) return `最近`
if (diffHours <= 24) return `${diffHours}小时前`
if (diffDays === 1) return `昨天`
if (diffDays === 2) return `前天`
if (diffDays <= 7) return `${diffDays}天前`

const year = timeObj.getFullYear()
const month = timeObj.getMonth() + 1
const date = timeObj.getDate()
return year !== currentDate.getFullYear() ? `${year}/${month}/${date}` : `${month}/${date}`
}

if (more) return formatTimestamp(time)
if (time) return describeTime(time)

document.querySelectorAll('time.datatime').forEach((e) => { e.textContent = describeTime(e.getAttribute('datetime')) })
}